2013-10-17 137 views
1

我在将新的pyqt5 signals and slots应用到脚本中遇到了一些麻烦,该脚本的目的是测试/调用我一直试图解决的另一个问题,GUI冻结/崩溃......目标是如此一旦这些信号和插槽运行正常,GUI将不会在运行时间+/- 30秒后发生崩溃,而只是继续计数直到时间结束。我已经提供了一个pyqt4的例子,尽管有一个pyqt5解决方案会很棒。谢谢:)Python PyQt5信号和插槽

from time import sleep 
import os 
from PyQt4 import QtCore, QtGui, uic 
from PyQt4.QtGui import * 
import random 
import os 
import time 


class Cr(QtCore.QThread): 
    def __init__(self): 
     QtCore.QThread.__init__(self) 
    def run(self): 

     while True: 
      rndInt = random.randint(1, 100000) 
      timesleep = random.random() 
      time.sleep(timesleep) 
      for i in range(120): 
       self.emit(QtCore.SIGNAL('host_UP'), 'foo' + str(rndInt), i) 
       QtGui.QApplication.processEvents() 


class Main_Window(QWidget): 

    def __init__(self, *args): 
     QWidget.__init__(self, *args) 
     self.relativePath = os.path.dirname(sys.argv[0]) 

     self.Main_Window = uic.loadUi("Main_Window.ui", self) 
     self.Main_Window.show() 
     self.Main_Window.move(790, 300) 

     self.GU = [] 
     ProgressThreads = self.printThreads 
     self.details_label = [] 
     for i in range(120): 
      self.details_label.insert(i, 0) 
      self.details_label[i] = QLabel(" ") 
      ProgressThreads.addWidget(self.details_label[i]) 
      ProgressThreads.addSpacing(6) 
      self.details_label[i].setText(Tools.Trim.Short('Idle', 7)) 
      self.GU.insert(i, Cr()) 
      self.GU[i].start() 

     self.connect(self.GU, QtCore.SIGNAL("host_UP"), self.UpdateHost) 


    def UpdateHost(self, str1, pos1): 
     self.details_label[pos1].setText(str1) 


class guiUpdate(): 
    def GUI_main(self): 
     self.GUI = GUI 



if __name__ == "__main__": 
    app = QApplication(sys.argv) 
    guiUpdate.GUI_main.GUI = Main_Window() 
    sys.exit(app.exec_()) 

谢谢你的帮助:)

UPDATE 下面的脚本是上面的脚本的希望正确PyQt5版本。然而崩溃和“没有响应”消息的问题仍未得到解决

from time import sleep 
import os 
from PyQt5 import QtCore, QtGui, uic 
from PyQt5.QtWidgets import * 
from PyQt5.QtCore import QObject, pyqtSignal 
import random 
import os 
import time 
import Tools 
import sys 


class Cr(QtCore.QThread): 
    def __init__(self, sam): 
     QtCore.QThread.__init__(self) 
     self.sam = sam 

    def run(self): 

     while True: 
      rndInt = random.randint(1, 100000) 
      timesleep = random.random() 
      time.sleep(timesleep) 
      for i in range(5): 
       #time.sleep(1) 

       self.sam.connect_and_emit_trigger('foo' + str(rndInt), i) 
       #self.emit(QtCore.SIGNAL('host_UP'), 'foo' + str(rndInt), i) 
       #QtGui.QApplication.processEvents() 


class Main_Window(QWidget): 

    def __init__(self, *args): 
     QWidget.__init__(self, *args) 
     self.relativePath = os.path.dirname(sys.argv[0]) 

     self.Main_Window = uic.loadUi("Main_Window.ui", self) 
     self.Main_Window.show() 
     self.Main_Window.move(790, 300) 

     sam = Foo() 


     self.GU = [] 
     ProgressThreads = self.ProgressThreads 
     self.details_label = [] 
     for i in range(5): 
      self.details_label.insert(i, 0) 
      self.details_label[i] = QLabel(" ") 
      ProgressThreads.addWidget(self.details_label[i]) 
      ProgressThreads.addSpacing(6) 
      self.details_label[i].setText(Tools.Trim.Short('Idle', 7)) 
      self.GU.insert(i, Cr(sam)) 
      self.GU[i].start() 


class Foo(QObject): 
    # Define a new signal called 'trigger' that has no arguments. 
    trigger = pyqtSignal() 
    def connect_and_emit_trigger(self, str, i): 
     self.str = str 
     self.i = i 

     self.trigger.connect(self.handle_trigger) 
     self.trigger.emit() 

    def handle_trigger(self): 
     guiUpdate.GUI_main.GUI.details_label[self.i].setText(self.str) 




class guiUpdate(): 
    def GUI_main(self): 
     self.GUI = GUI 



if __name__ == "__main__": 
    app = QApplication(sys.argv) 
    guiUpdate.GUI_main.GUI = Main_Window() 
    sys.exit(app.exec_()) 
+0

你可以附加Main_Window.ui文件吗? –

回答

0

新推荐的方法使用线程(和我得到了最好的结果之一)是使用moveToThread(),而不是直接继承的QThread。简而言之:

  1. 写一个做实际工作的QObject子类(我们称之为QMyWorker)。这可能会看起来有点像现有的QThread子类,具有start()run()方法等

  2. 创建

  3. QMyWorker

    的家长少实例创建
  4. 的QThread

    的家长少实例

    使用QMyWorker.moveToThread(your_thread_instance)(我按内存去,仔细检查doc中的API)。

  5. 打电话给你QMyWorker.start()

这种方式为我工作很长时间的工作(4GB文件等)。