如何将小部件连接到在一个类中声明的自定义信号,同时在另一个类中声明

2024-09-30 20:26:28 发布

您现在位置:Python中文网/ 问答频道 /正文

简短描述: 有两个线程与七个队列项一起声明。对于每个队列项,都创建了QProgressBar,并使用queue的setValue()方法将其实例分配给每个队列项。在线程的run()方法内部,QProgressBar实例是使用队列项的get()方法检索的。当仍然在run()方法内部时,QProgressBar实例连接到一个定制的“updateBar”信号,因此可以从运行run()方法的内部(或从任何其他线程的方法)更新进度条小部件。虽然代码似乎运行良好,但如果我在MyWindow类之外将QProgressBar实例连接到Signal时做了正确的事情(到Signal的连接是在Thread类内部建立的),我想听听您的意见。我实施的方法有什么复杂之处吗。还是我应该用别的东西?你知道吗

enter image description here

from PyQt4 import QtCore, QtGui
import Queue as queue

class PbWidget(QtGui.QProgressBar):
    def __init__(self, parent=None):
        super(PbWidget, self).__init__()
        self.setMinimum(1)
        self.setMaximum(100)        
        self._active = False  

    def update_bar(self, argValue):
        self.setValue(argValue)
        QtGui.qApp.processEvents()

    def closeEvent(self, event):
        self._active = False

class MyThread(QtCore.QThread):
    def __init__(self, queue, parent=None):
        QtCore.QThread.__init__(self, parent)
        self.queue = queue
    def run(self):
        while True:
            pb = self.queue.get()
            pb.connect(self, QtCore.SIGNAL("updateBar"), pb.update_bar)
            for i in range(0,11):
                self.emit(QtCore.SIGNAL("updateBar"), i*10) 
                self.sleep(1) 
            self.queue.task_done()
            pb.disconnect(self, QtCore.SIGNAL("updateBar"), pb.update_bar)

class MyWindow(QtGui.QMainWindow):
    def __init__(self, parent=None):
        super(MyWindow, self).__init__(parent)
        self.queue = queue.Queue()

        cWidget = QtGui.QWidget(self)
        self.setCentralWidget(cWidget)
        self.layout = QtGui.QVBoxLayout(cWidget)
        button=QtGui.QPushButton("Sumbit Threads")
        button.clicked.connect(self.submitThreads)
        self.layout.addWidget(button)

    def submitThreads(self):
        self.threads = []
        for i in range(1, 3): 
            thread = MyThread(self.queue)
            self.threads.append(thread)            
            thread.start()

        numbers=[1,2,3,4,5,6,7]
        for number in numbers:
            pb=PbWidget()
            self.layout.addWidget(pb)
            self.queue.put(pb) 

if __name__ == "__main__":
    import sys
    app = QtGui.QApplication(sys.argv)
    window = MyWindow()
    window.resize(300, 30)
    window.show()
    sys.exit(app.exec_())

Tags: 实例方法runself队列queueinitdef
1条回答
网友
1楼 · 发布于 2024-09-30 20:26:28

既然你已经开始了,我不明白你为什么要改变。你知道吗

就我个人而言,我不会在线程之间传递对象(即progress小部件),因为这不会扩展到多进程、集群等,也不能同时从不同的线程获取/设置相同的变量。你知道吗

我使用的另一种方法是传递简单的状态消息,让主线程中的QTimer定期检查传入队列(使用get\u nowait()),并适当地设置接口。你知道吗

例如,在GUI init上设置计时器:

    self.timer = QTimer(self)
    self.timer.timeout.connect(self.timeout)
    self.timer.start(100)

在超时方法中:

    coming = self.incoming.get_nowait()

其中incoming是其他线程/进程可以写入的队列。在您的例子中,数据将包含进度条标识符和进度值。当没有数据等待时,get\u nowait将引发一个空异常。你知道吗

有趣的是,如果你调用pb.U栏()直接,而不是使用信号机制?你知道吗

相关问题 更多 >