关于python:相当于time.sleep?

equivalent to time.sleep?

我无法在pyqt应用程序中使用time.sleep,因为它冻结了GUI线程,因此在此期间,GUI将被完全冻结。我一直在寻找一种解决方法。

我尝试使用QTimer,但似乎需要将它们链接到另一个函数? 像等待十秒钟,然后运行一些功能。 有没有办法让它等待然后继续当前功能?

1
2
3
4
5
6
7
def num(self):
    for i in range(1,999):
        print i
        #Add some sleep here

def testSleep(self):
    QtCore.QTimer.singleShot(2000, self.num)


实际上,我一直在寻找在pyqt中使用的time.sleep替代方案,而不使用任何线程概念。

我想出的解决方案是:

1
2
3
from PyQt4 import QtTest

QtTest.QTest.qWait(msecs)

这类似于time.sleep使GUI响应。

谢谢您的回答。


也许可以做得更好,但是您始终可以使用singleShot来延迟运行函数,并使用lambda来运行带有参数的函数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import sys
from PyQt4 import QtGui, QtCore

#def num(self, i):
def num(i):
    print i
    i += 1
    if i < 999:
        # run again after 2000ms with argument
        QtCore.QTimer.singleShot(2000, lambda:num(i))
        #QtCore.QTimer.singleShot(2000, lambda:self.num(i))

app = QtGui.QApplication(sys.argv)

# run first time with start argument
num(1)
#QtCore.QTimer.singleShot(2000, lambda:num(1))

sys.exit(app.exec_())


我相信您正在问,如果num()需要几秒钟才能运行,如何保持GUI响应?您有两种选择:

  • 如果num()由许多"工作"小块组成,则可以在这些块之间调用application.processEvents(),这将允许GUI响应事件。一个简单的情况是,大多数num()时间都花在一个循环中,然后在每次迭代的开始或结束时调用application.processEvents()。在您的实际应用程序中,如果您无权访问application,请从PyQt4导入qApp
  • 更好的方法是在单独的线程中执行num()。在SO上有很多这样的例子(像这样)。一种方法是

    • 实例化QThread
    • 定义一个从QObject派生并定义num(self)的类(例如NumberCruncher),并定义在返回之前由num()发出的信号"完成"
    • 致电numberCruncher.moveToThread(thread)
    • 将线程started信号连接到num
    • 启动线程


您不能在pyqt主事件循环中使用time.sleep,因为它会停止GUI事件循环的响应。

使用QTimer的pyqt中的解决方案如下所示

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import sys
from PyQt4 import QtGui, QtCore

application = QtGui.QApplication(sys.argv)

i=0
timer = QtCore.QTimer()

def num():
    global i, timer
    if i <999:
        print ( i )
        i += 1
    else:
        timer.stop()

timer.timeout.connect(num)
timer.start(2000)

sys.exit(application.exec_())