QDialog.show()方法有一个延迟反应

时间:2014-02-06 01:22:28

标签: python pyqt pyqt4 show qdialog

我有一个问题,我不知道有一段时间了。我有一个主窗口应用程序和一个QDialog,它应该在单击其中一个按钮后弹出,但QDialog上的show()方法似乎正在等待连接到“clicked()”信号的函数结束! 我希望在调用QDialog.show()方法后立即显示对话框,而不是在该函数中的所有其他代码指令之后...

当然,在我的代码中,我将用更复杂的代码替换sleep(5)部分,但是这描绘了问题,我放在那里的代码与问题无关,我认为(数据库连接和更新) 更具体:

# -*- coding: utf-8 -*-
import sys

import PyQt4 
from PyQt4 import QtCore, QtGui
from twython import Twython, TwythonError
from project import Ui_MainWindow
from time import sleep
import psycopg2, globalvals, updater
import updating, noconnection

class UpWindow(QtGui.QDialog):
    def __init__(self, parent=None):
        QtGui.QDialog.__init__(self, parent, QtCore.Qt.WindowStaysOnTopHint)
        self.ui = updating.Ui_updating()
        self.ui.setupUi(self)

class NoConnection(QtGui.QDialog):
    def __init__(self, parent=None):
        QtGui.QDialog.__init__(self, parent, QtCore.Qt.WindowStaysOnTopHint)
        self.ui = noconnection.Ui_noConnection()
        self.ui.setupUi(self)

        QtCore.QObject.connect(self.ui.noConnectionClose, QtCore.SIGNAL("clicked()"), self.close)

class MyCounter(QtGui.QWidget):
    def __init__(self, parent=None):
        QtGui.QWidget.__init__(self, parent)
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)
        self.noConn = NoConnection(self)
        self.upWin = UpWindow(self)

        QtCore.QObject.connect(self.ui.refreshButton,QtCore.SIGNAL("clicked()"), self.refresh)
        QtCore.QObject.connect(self.ui.manageButton,QtCore.SIGNAL("clicked()"), self.manage)

    def refresh(self):
        self.upWin.show()
        self.upWin.show
        self.upWin.setVisible(True)
        self.setEnabled(False)
        self.upWin.setEnabled(True)
        #Thats the issue - the sleep instruction is being held
        #BEFORE the showing of upWin QDialog
        sleep(5)

    def manage(self):
        print 'ok'



if __name__ == "__main__":
    app = QtGui.QApplication(sys.argv)
    myapp = MyCounter()
    myapp.upcontent()
    myapp.show()
    sys.exit(app.exec_())

2 个答案:

答案 0 :(得分:1)

将任何Qt程序视为协作多任务系统。图形和事件通常由主循环处理。你不想在任何一个插槽中呆很长时间,因为图书馆不会同时处理信号(比如按钮点击,重新绘制,还有其他东西)。

如果你想做一些繁重的处理,或者在程序的其余部分同时需要等待资源的任何事情,请使用QThread

另一种选择是强制使用qApp.processEvents()(您可以在qApp中找到QtGui)的事件处理,就在sleep(5)之前(或者您要去的任何代码)代替它。)

编辑:现在,请记住,强制事件处理只会显示您尝试弹出的QDialog。如果不再调用qApp.processEvents()或从插槽返回,你就无法做任何事情(请记住,没有事件处理)。

答案 1 :(得分:0)

如果MyCounter表示执行长计算并在此期间更新对话框的窗口小部件,则sleep(5)不代表它,因为在这5秒内GUI无法处理事件。对于“长时间运行”功能,您可以将阻塞部分移动到QThread并轮询线程或连接到它发展时发出的信号,无论哪种方式,您都不会在此期间阻止GUI事件循环(例如,轮询只需要很少的时间,就会在空闲的回调中发生。创建测试的最简单方法是使用定时回调到MyCounter:

def refresh(self):
    ... show stuff, then:
    self.timer = QTimer()
    self.timer.timeout.connect(self.updateDialog)
    timer.start(100) # 10 times per sec

def updateDialog(self):
    #get thread status
    if self.thread.status != self.oldStatus:
        self.upWin.updateStatus( self.thread.status )