PYQT4 多线程问题请教

qq_36893425 2017-07-13 10:57:34
我用pyqt4做了个界面,一个button,两个label(label和label1),程序目的:点击button按钮,label和label1上同时并各自依次显示,黄灯,灰灯,红灯,绿灯,想法是一个按钮的单击事件,连接了两个槽,
QtCore.QObject.connect(self.pushButton2, QtCore.SIGNAL(_fromUtf8("clicked()")),self.changePic)
QtCore.QObject.connect(self.pushButton2, QtCore.SIGNAL(_fromUtf8("clicked()")),self.changePic2)
但是运行的结果是,第一个label的图片先依次显示黄灯,灰灯,红灯,绿灯,接着再试第二个label1显示黄灯,灰灯,红灯,绿灯,两个label并没有同时开始动作,
如果要两个label同时开始显示同样的图片,是不是需要进行多线程编写,应该怎么写,谢谢

- 灯素材如下




- 目标运行效果


- 完整代码如下:
from PyQt4.QtGui import QApplication, QLabel, QMovie, QPainter, QFontMetrics,QPixmap
import time
from PyQt4 import QtCore, QtGui

try:
_fromUtf8 = QtCore.QString.fromUtf8
except AttributeError:
def _fromUtf8(s):
return s

try:
_encoding = QtGui.QApplication.UnicodeUTF8
def _translate(context, text, disambig):
return QtGui.QApplication.translate(context, text, disambig, _encoding)
except AttributeError:
def _translate(context, text, disambig):
return QtGui.QApplication.translate(context, text, disambig)

class Ui_Dialog(object):
def __init__(self):
self.m=QPixmap("I:/python/icon/shuijing/039/yellow.png")
self.x=QPixmap("I:/python/icon/shuijing/039/yellow.png")


def setupUi(self, Dialog):

Dialog.setObjectName(_fromUtf8("Dialog"))
Dialog.resize(654, 535)
self.label = QLabel(Dialog)
self.label.setGeometry(QtCore.QRect(80, 50, 200, 200))
self.label.setObjectName(_fromUtf8("label"))
self.label1 = QLabel(Dialog)
self.label1.setGeometry(QtCore.QRect(280, 50, 200, 200))
self.label1.setObjectName(_fromUtf8("label1"))
self.pushButton2 = QtGui.QPushButton(Dialog)
self.pushButton2.setGeometry(QtCore.QRect(170, 400, 191, 61))
self.pushButton2.setText('start')
self.pushButton2.setObjectName(_fromUtf8("pushButton2"))
#QtCore.QObject.connect(self.pushButton, QtCore.SIGNAL(_fromUtf8("clicked()")),self.stop1)
QtCore.QObject.connect(self.pushButton2, QtCore.SIGNAL(_fromUtf8("clicked()")),self.changePic)
QtCore.QObject.connect(self.pushButton2, QtCore.SIGNAL(_fromUtf8("clicked()")),self.changePic2)

#self.label.setMovie(self.m)
self.label.setScaledContents(True)
self.label.setPixmap(self.m)
self.label1.setScaledContents(True)
self.label1.setPixmap(self.x)

self.retranslateUi(Dialog)
QtCore.QMetaObject.connectSlotsByName(Dialog)

def changePic(self):
self.b=QPixmap("I:/python/icon/shuijing/039/grey.png")
self.label.setScaledContents(True)
self.label.setPixmap(self.b)
self.label.repaint()
time.sleep(2)
self.n=QPixmap("I:/python/icon/shuijing/039/red.png")
self.label.setScaledContents(True)
self.label.setPixmap(self.n)
self.label.repaint()
time.sleep(2)
self.h=QPixmap("I:/python/icon/shuijing/039/green.png")
self.label.setScaledContents(True)
self.label.setPixmap(self.h)
#self.label.repaint()"""


def changePic2(self):
self.y=QPixmap("I:/python/icon/shuijing/039/grey.png")
self.label1.setScaledContents(True)
self.label1.setPixmap(self.y)
self.label1.repaint()
time.sleep(2)
self.p=QPixmap("I:/python/icon/shuijing/039/red.png")
self.label1.setScaledContents(True)
self.label1.setPixmap(self.p)
self.label1.repaint()
time.sleep(2)
self.k=QPixmap("I:/python/icon/shuijing/039/green.png")
self.label1.setScaledContents(True)
self.label1.setPixmap(self.k)
#self.label1.repaint()

def retranslateUi(self, Dialog):
Dialog.setWindowTitle(_translate("Dialog", "Dialog", None))
#self.label.setText(_translate("Dialog", "TextLabel", None))

def main():
app = QtGui.QApplication(sys.argv)
Dialog = QtGui.QDialog()
ui = Ui_Dialog()
ui.setupUi(Dialog)
Dialog.show()
sys.exit(app.exec_())

if __name__ == "__main__":
import sys

main()
...全文
523 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
手无护鸡之力 2017-07-24
  • 打赏
  • 举报
回复

class MyThread(QtCore.QThread):
    trigger = QtCore.pyqtSignal(str)
     
    def __init__(self,parent=None):  
        super(MyThread, self).__init__(parent)
 
    def run(self):
        # your task code
        self.Lable2Action()
        self.exec_()
         
      
    global num2
    num2=0    
    def timeOut2(self):
        global num2
        #num=num+1        
        num2=num2+1
        if (num2%2==0):
             self.trigger.emit("G:/python/icon/shuijing/039/red.png") 
        else:
            self.trigger.emit("G:/python/icon/shuijing/039/grey.png")
        #pass
    def Lable2Action(self): 
            self.timer2=QtCore.QTimer()
            self.timer2.setInterval(500)
            self.timer2.start()
            QtCore.QObject.connect(self.timer2,QtCore.SIGNAL("timeout()"),self.timeOut2)
手无护鸡之力 2017-07-24
  • 打赏
  • 举报
回复
引用 9 楼 qq_36893425 的回复:
@管理員 谢谢,你的办法是对的, 但为什么定时器没起效,执行self.Lable2Action() 的过程中,不是让定时器起作用吗,为什么没起作用,能不能再给解释的详细点,如果还是要用定时器的办法去做呢,应该怎么做 这里面我的思路可能有点问题,定时器没起作用这块还没弄明白,麻烦指导下,纠正下我的思维
For QTimer to work, you must have an event loop in your application; that is, you must call QCoreApplication::exec() somewhere. Timer events will be delivered only while the event loop is running.

In multithreaded applications, you can use QTimer in any thread that has an event loop. To start an event loop from a non-GUI thread, use QThread::exec(). Qt uses the timer's thread affinity to determine which thread will emit thetimeout() signal. Because of this, you must start and stop the timer in its thread; it is not possible to start a timer from another thread.
https://stackoverflow.com/questions/10492480/starting-qtimer-in-a-qthread
qq_36893425 2017-07-21
  • 打赏
  • 举报
回复
@管理員 谢谢,你的办法是对的, 但为什么定时器没起效,执行self.Lable2Action() 的过程中,不是让定时器起作用吗,为什么没起作用,能不能再给解释的详细点,如果还是要用定时器的办法去做呢,应该怎么做 这里面我的思路可能有点问题,定时器没起作用这块还没弄明白,麻烦指导下,纠正下我的思维
qq_36893425 2017-07-18
  • 打赏
  • 举报
回复
from PyQt4.QtGui import QApplication, QLabel, QMovie, QPainter, QFontMetrics,QPixmap

import time


from PyQt4 import QtCore, QtGui

try:
    _fromUtf8 = QtCore.QString.fromUtf8
except AttributeError:
    def _fromUtf8(s):
        return s

try:
    _encoding = QtGui.QApplication.UnicodeUTF8
    def _translate(context, text, disambig):
        return QtGui.QApplication.translate(context, text, disambig, _encoding)
except AttributeError:
    def _translate(context, text, disambig):
        return QtGui.QApplication.translate(context, text, disambig)
    


class Ui_Dialog(object):
    def __init__(self):
        #super(Ui_Dialog, self).__init__()
        self.m=QPixmap("G:/python/icon/shuijing/039/yellow.png")
        self.x=QPixmap("G:/python/icon/shuijing/039/yellow.png")
        self.thread = MyThread()
        self.thread.trigger.connect(self.Lable2Show)
         
         
    def setupUi(self, Dialog):
         
        Dialog.setObjectName(_fromUtf8("Dialog"))
        Dialog.resize(700, 600)
        self.label = QLabel(Dialog)
        self.label.setGeometry(QtCore.QRect(80, 50, 200, 200))
        self.label.setObjectName(_fromUtf8("label"))
        self.label1 = QLabel(Dialog)
        self.label1.setGeometry(QtCore.QRect(280, 50, 200, 200))
        self.label1.setObjectName(_fromUtf8("label1"))
        self.pushButton = QtGui.QPushButton(Dialog)
        self.pushButton.setGeometry(QtCore.QRect(170, 300, 191, 61))
        self.pushButton.setText('Stop')
        self.pushButton.setObjectName(_fromUtf8("pushButton"))
        self.pushButton2 = QtGui.QPushButton(Dialog)
        self.pushButton2.setGeometry(QtCore.QRect(170, 400, 191, 61))
        self.pushButton2.setText('myThread')
        self.pushButton2.setObjectName(_fromUtf8("pushButton2"))
        self.pushButton3 = QtGui.QPushButton(Dialog)
        self.pushButton3.setGeometry(QtCore.QRect(170, 500, 191, 61))
        self.pushButton3.setText('start')
        self.pushButton3.setObjectName(_fromUtf8("pushButton3"))
        QtCore.QObject.connect(self.pushButton, QtCore.SIGNAL(_fromUtf8("clicked()")),self.stop1)
        QtCore.QObject.connect(self.pushButton2, QtCore.SIGNAL(_fromUtf8("clicked()")),self.myThread)
        QtCore.QObject.connect(self.pushButton3, QtCore.SIGNAL(_fromUtf8("clicked()")),self.start)
        #QtCore.QObject.connect(self.pushButton2, QtCore.SIGNAL(_fromUtf8("clicked()")),self.changePic2)

        #self.label.setMovie(self.m)
        self.label.setScaledContents(True)
        self.label.setPixmap(self.m)
        self.label1.setScaledContents(True)
        self.label1.setPixmap(self.x)

        self.retranslateUi(Dialog)
        QtCore.QMetaObject.connectSlotsByName(Dialog)
        
    def start(self):
        self.timer=QtCore.QTimer()
        self.timer.setInterval(500)
        self.timer.start()
        QtCore.QObject.connect(self.timer,QtCore.SIGNAL("timeout()"),self.timeOut)

    global num
    num=0  
    def timeOut(self):
        global num
        #num=num+1        
        num=num+1
        if (num%2==0):
             self.b=QPixmap("G:/python/icon/shuijing/039/red.png") 
             self.label.setScaledContents(True)
             self.label.setPixmap(self.b)
             self.label.repaint()

        else:
             self.b=QPixmap("G:/python/icon/shuijing/039/green.png") 
             self.label.setScaledContents(True)
             self.label.setPixmap(self.b)
             self.label.repaint()
             
    def myThread(self):

        self.thread.start() 
        
  
    def Lable2Show(self,str1): 
        
             #self.b=QPixmap("I:/python/icon/shuijing/039/red.png")
             self.h=QPixmap(str1) 
             self.label1.setScaledContents(True)
             self.label1.setPixmap(self.h)
             self.label1.repaint()
                        
    def stop1(self):
        #flag=0
        self.timer.stop()
        self.b=QPixmap("G:/python/icon/shuijing/039/green.png") 
        self.label.setScaledContents(True)
        self.label.setPixmap(self.b)
        #self.thread.terminate()
        
    def retranslateUi(self, Dialog):
        Dialog.setWindowTitle(_translate("Dialog", "Dialog", None))
        
class MyThread(QtCore.QThread):
    trigger = QtCore.pyqtSignal(str)
    
    def __init__(self,parent=None):  
        super(MyThread, self).__init__(parent)

    def run(self):
        # your task code
        self.Lable2Action()
        
     
    global num2
    num2=0    
    def timeOut2(self):
        global num2
        #num=num+1        
        num2=num2+1
        if (num%2==0):
             self.trigger.emit("G:/python/icon/shuijing/039/red.png") 
        else:
            self.trigger.emit("G:/python/icon/shuijing/039/grey.png")
        #pass
    def Lable2Action(self): 
            self.timer2=QtCore.QTimer()
            self.timer2.setInterval(500)
            self.timer2.start()
            QtCore.QObject.connect(self.timer2,QtCore.SIGNAL("timeout()"),self.timeOut2)
             
             
def main():
     
    app = QtGui.QApplication(sys.argv)
    Dialog = QtGui.QDialog()
    ui = Ui_Dialog()
    ui.setupUi(Dialog)
    Dialog.show()
    sys.exit(app.exec_())
    
if __name__ == "__main__":
    import sys
    
    main()
@wn0112 帮忙看下我创建的那个线程为什么没有成功
手无护鸡之力 2017-07-18
  • 打赏
  • 举报
回复
因为你的线程执行完self.Lable2Action() 结束关闭了,不会管你的什么timer定时器。 MyThread应该这么写:

class MyThread(QtCore.QThread):
    trigger = QtCore.Signal(str)
    def __init__(self,parent=None):
        super(MyThread, self).__init__(parent)

    def run(self):
        num=0 
        while True:
            num += 1
            if (num%2==0):
                self.trigger.emit("G:/python/icon/shuijing/039/red.png") 
            else:
                self.trigger.emit("G:/python/icon/shuijing/039/grey.png")
            time.sleep(0.2)
        
qq_36893425 2017-07-15
  • 打赏
  • 举报
回复
非常感谢!
手无护鸡之力 2017-07-14
  • 打赏
  • 举报
回复
引用 3 楼 qq_36893425 的回复:
多谢指教,明白了,可以用定时器来替换sleep()函数 另外再请教一个问题: 我想做个程序,一个按钮,一个label,一张黄和一张灰图片,点击按钮,就跑我的某个任务 1.当任务还在跑的过程中,Qlabel上的图片类似于告警灯那样在闪烁(用黄灯和灰灯交替显示的方式-闪烁的视觉效果),表示任务在进行中 2.当我任务完成后,label最后变成了绿灯 这种方式是不是应该算多线程了,大体上应该用什么思路怎么去实现
要用多线程。按下按钮,线程start, 开始跑任务,Label开始闪烁,线程内任务完成,发信号给UI,Label停止闪烁复原
qq_36893425 2017-07-14
  • 打赏
  • 举报
回复
多谢指教,明白了,可以用定时器来替换sleep()函数 另外再请教一个问题: 我想做个程序,一个按钮,一个label,一张黄和一张灰图片,点击按钮,就跑我的某个任务 1.当任务还在跑的过程中,Qlabel上的图片类似于告警灯那样在闪烁(用黄灯和灰灯交替显示的方式-闪烁的视觉效果),表示任务在进行中 2.当我任务完成后,label最后变成了绿灯 这种方式是不是应该算多线程了,大体上应该用什么思路怎么去实现
手无护鸡之力 2017-07-14
  • 打赏
  • 举报
回复
还有,你写UI程序 ,不能在UI线程里用time.sleep(), 这样界面会卡住不动的
手无护鸡之力 2017-07-14
  • 打赏
  • 举报
回复
你这样写肯定是这种效果了,因为changePic与changePic2在同一线程内调用,并不能并行。 既然2个label变化相同,不用写2个槽函数 ,把按钮的click事件连接一个槽函数 ,在这个槽函数里控制2个label的变化,这样看起来就是同时了
手无护鸡之力 2017-07-14
  • 打赏
  • 举报
回复

        
class MainWindow(QMainWindow):
    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)
        self.button = QPushButton(self, 'Start')
        self.button.clicked.connect(self.clickButton)
        self.th = MyThread(self)
        self.th.finished.connect(self.stopAnimation)
        
    def stopAnimation(self):
        pass

    def startAnimation(self):
        pass

    def clickButton(self):
        self.startAnimation()
        self.th.start()

class MyThread(QThread):
    def run(self):
        # your task code
        pass
       

37,719

社区成员

发帖
与我相关
我的任务
社区描述
JavaScript,VBScript,AngleScript,ActionScript,Shell,Perl,Ruby,Lua,Tcl,Scala,MaxScript 等脚本语言交流。
社区管理员
  • 脚本语言(Perl/Python)社区
  • IT.BOB
加入社区
  • 近7日
  • 近30日
  • 至今

试试用AI创作助手写篇文章吧