在QThread循环中截取屏幕截图导致应用程序退出

时间:2015-04-25 08:04:58

标签: python pyqt

使用以下代码,我可以使用PyQt创建一个启动画面,然后生成一个发出信号以更新QLabel的线程。 QThread有一个定时器延迟循环,它发出一个包含QString的信号,当主应用程序收到它时,启动屏幕上的QLabel会动态更新:所以我已经验证了这种通用方法是有效的。

问题是当我尝试在循环的每次迭代中截取屏幕截图时。我所看到的是,应用程序只是退出而没有任何错误消息或警告。 print语句表明它是截图步骤,它以某种方式导致应用程序退出,即删除这一行使应用程序正常运行。

有没有办法解决这个问题,或者至少找出可能导致此问题的原因?

from PyQt4 import QtCore
from PyQt4.QtCore import (Qt, SIGNAL, pyqtSignal, QObject)
from PyQt4.QtGui import (QApplication, QDialog, QLineEdit, QTextBrowser,
        QVBoxLayout, QPushButton, QSplashScreen, QLabel)
import random
import time
import sys
import pyscreenshot
class Worker(QtCore.QThread):
    def __init__(self, parent=None):
        QtCore.QThread.__init__(self)
        print("hello world")


    def __del__(self):
        self.wait()
        print 'del'
    def run(self):

        print 'in'
        while True:
            time.sleep(1)
            a = range(0, 500)

            pyscreenshot.grab_to_file('/home/rm/f.png') #this is the problem
            self.emit( QtCore.SIGNAL('update(QString)'), "<font color=red size=72><b>{0}</b></font>".format(str(random.choice(a))) )   


class Form(QDialog):

    def __init__(self, parent=None): 
        super(Form, self).__init__(parent)
        message = 'hello'

        self.label = QLabel("<font color=red size=72><b>{0}</b></font>".format(message))
        self.setWindowFlags(Qt.SplashScreen)
        self.setAttribute(Qt.WA_TranslucentBackground)

        self.label.show()  
        self.resize(1250, 50)

        okButton = QPushButton("&OK")
        layout = QVBoxLayout()
        layout.addWidget(self.label)
        layout.addWidget(okButton)
        self.setLayout(layout)
        self.connect(okButton, SIGNAL("clicked()"),self.run)

    def changelab(self, msg):
        print '************************', msg
        self.label.setText(msg)


    def run(self):

        self.workThread = Worker()
        self.connect( self.workThread, QtCore.SIGNAL("update(QString)"), self.changelab )
        self.workThread.start()      



app = QApplication(sys.argv)
form = Form()
form.show()
app.exec_()

1 个答案:

答案 0 :(得分:1)

我怀疑Pyscreenshot的PyQt后端不是线程安全的。看起来它使用QTimer s,快速谷歌指示不应该在GUI线程之外使用。我建议强制使用不同的后端(如果有线程安全)或使用{{1}}从主线程中截取屏幕截图。