Python中的冻结Qt GUI
Posted
技术标签:
【中文标题】Python中的冻结Qt GUI【英文标题】:Frozen Qt GUI in Python 【发布时间】:2014-07-15 17:17:07 【问题描述】:我正在用 Python 中的 QT gui 编写一个计时器应用程序,它工作得很好,直到我使用少于 5 分钟的数字。当我使用大于 300 秒的数字时,它会冻结。应该在哪里出错?谢谢。 (现在只实现了倒计时)
from PyQt4 import QtCore, QtGui
from PyQt4.QtCore import *
from threading import Timer
class Drawer(QObject):
def __init__(self,i=0,j=47):
QObject.__init__(self)
self.i=i
self.j=j
self.begin=self.j
'''def run(self):
self.exec_()'''
def signal_emitter_upcount(self):
print self.i
self.i=self.i+1
print '\n'
def signal_emitter_downcount(self):
self.emit(SIGNAL("asignal"))
#timer.cancel()
def connected_from_main_thread(self):
'''
called from main thread connected by signals
'''
if(self.j!=0): #for sure (numbers not < 0)
self.j=self.j-1
self.percent=int (100-(float (self.j)/float(self.begin)*100))#how many percent is done
ui.lcdNumber_8.setProperty("value", time_format_converter(self.j)[-1])
ui.lcdNumber_11.setProperty("value", time_format_converter(self.j)[-2])
ui.lcdNumber_7.setProperty("value", time_format_converter(self.j)[-3])
ui.lcdNumber_9.setProperty("value", time_format_converter(self.j)[-4])
ui.lcdNumber_10.setProperty("value", time_format_converter(self.j)[-5])
ui.progressBar.setProperty("value",self.percent)
#ui.progressBar.setProperty("value",self.percent)
#print self.j
class Watch(object):
def __init__(self, type="Counter", seconds = 60):
self.drawer = Drawer(j = seconds,i=0)
if(type=="Countdown"):
self.seconds = seconds + 1
self.watch = Countdown(value = self.seconds)
if(type=="Counter"):
self.seconds = seconds + 1
self.watch = Counter(value = self.seconds)
class Countdown(object):
def __init__(self, value=50):
self.value=value
def run_me(self):
for x in xrange(1,self.value+2):
timer = Timer(0.1*x, watch.drawer.signal_emitter_downcount)
timer.start()
'''if(x==self.value):
timer.cancel()'''
def stop_countdown(self):
pass
class Counter(object):
def __init__(self, value=30):
self.value=value
def run(self):
for x in xrange(1,self.value+2):
print gui_final.watch
timer = Timer(0.1*x, watch.drawer.signal_emitter_upcount)
timer.start()
if(x==self.value+1):
timer.cancel()
def stop_counter(self):
pass
try:
_fromUtf8 = QtCore.QString.fromUtf8
except AttributeError:
def _fromUtf8(s):
return s
try:
_encoding = QtGui.QApplication.UnicodeUTF8
def _translate(context, text, disambig):
return QtGui.QApplication.translate(context, text, disambig, _encoding)
except AttributeError:
def _translate(context, text, disambig):
return QtGui.QApplication.translate(context, text, disambig)
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName(_fromUtf8("MainWindow"))
MainWindow.resize(1024, 700)
self.centralwidget = QtGui.QWidget(MainWindow)
self.centralwidget.setObjectName(_fromUtf8("centralwidget"))
self.gridLayout_3 = QtGui.QGridLayout(self.centralwidget)
self.gridLayout_3.setObjectName(_fromUtf8("gridLayout_3"))
self.horizontalLayout = QtGui.QHBoxLayout()
self.horizontalLayout.setObjectName(_fromUtf8("horizontalLayout"))
self.lcdNumber_5 = QtGui.QLCDNumber(self.centralwidget)
self.lcdNumber_5.setNumDigits(1)
self.lcdNumber_5.setDigitCount(1)
self.lcdNumber_5.setProperty("intValue", 0)
self.lcdNumber_5.setObjectName(_fromUtf8("lcdNumber_5"))
self.horizontalLayout.addWidget(self.lcdNumber_5)
self.lcdNumber_6 = QtGui.QLCDNumber(self.centralwidget)
self.lcdNumber_6.setNumDigits(1)
self.lcdNumber_6.setDigitCount(1)
self.lcdNumber_6.setProperty("intValue", 0)
self.lcdNumber_6.setObjectName(_fromUtf8("lcdNumber_6"))
self.horizontalLayout.addWidget(self.lcdNumber_6)
self.line = QtGui.QFrame(self.centralwidget)
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Minimum)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.line.sizePolicy().hasHeightForWidth())
self.line.setSizePolicy(sizePolicy)
self.line.setFrameShape(QtGui.QFrame.VLine)
self.line.setFrameShadow(QtGui.QFrame.Sunken)
self.line.setObjectName(_fromUtf8("line"))
self.horizontalLayout.addWidget(self.line)
self.lcdNumber_10 = QtGui.QLCDNumber(self.centralwidget)
self.lcdNumber_10.setNumDigits(1)
self.lcdNumber_10.setDigitCount(1)
self.lcdNumber_10.setProperty("intValue", 0)
self.lcdNumber_10.setObjectName(_fromUtf8("lcdNumber_10"))
self.horizontalLayout.addWidget(self.lcdNumber_10)
self.lcdNumber_9 = QtGui.QLCDNumber(self.centralwidget)
self.lcdNumber_9.setNumDigits(1)
self.lcdNumber_9.setDigitCount(1)
self.lcdNumber_9.setProperty("intValue", 0)
self.lcdNumber_9.setObjectName(_fromUtf8("lcdNumber_9"))
self.horizontalLayout.addWidget(self.lcdNumber_9)
self.line_2 = QtGui.QFrame(self.centralwidget)
self.line_2.setFrameShape(QtGui.QFrame.VLine)
self.line_2.setFrameShadow(QtGui.QFrame.Sunken)
self.line_2.setObjectName(_fromUtf8("line_2"))
self.horizontalLayout.addWidget(self.line_2)
self.lcdNumber_7 = QtGui.QLCDNumber(self.centralwidget)
self.lcdNumber_7.setNumDigits(1)
self.lcdNumber_7.setDigitCount(1)
self.lcdNumber_7.setProperty("intValue", 0)
self.lcdNumber_7.setObjectName(_fromUtf8("lcdNumber_7"))
self.horizontalLayout.addWidget(self.lcdNumber_7)
self.lcdNumber_11 = QtGui.QLCDNumber(self.centralwidget)
self.lcdNumber_11.setNumDigits(1)
self.lcdNumber_11.setDigitCount(1)
self.lcdNumber_11.setProperty("intValue", 0)
self.lcdNumber_11.setObjectName(_fromUtf8("lcdNumber_11"))
self.horizontalLayout.addWidget(self.lcdNumber_11)
self.line_3 = QtGui.QFrame(self.centralwidget)
self.line_3.setFrameShape(QtGui.QFrame.VLine)
self.line_3.setFrameShadow(QtGui.QFrame.Sunken)
self.line_3.setObjectName(_fromUtf8("line_3"))
self.horizontalLayout.addWidget(self.line_3)
self.lcdNumber_8 = QtGui.QLCDNumber(self.centralwidget)
self.lcdNumber_8.setNumDigits(1)
self.lcdNumber_8.setDigitCount(1)
self.lcdNumber_8.setProperty("intValue", 0)
self.lcdNumber_8.setObjectName(_fromUtf8("lcdNumber_8"))
self.horizontalLayout.addWidget(self.lcdNumber_8)
self.gridLayout_3.addLayout(self.horizontalLayout, 0, 0, 1, 3)
self.horizontalLayout_2 = QtGui.QHBoxLayout()
self.horizontalLayout_2.setObjectName(_fromUtf8("horizontalLayout_2"))
self.progressBar = QtGui.QProgressBar(self.centralwidget)
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Preferred)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.progressBar.sizePolicy().hasHeightForWidth())
self.progressBar.setSizePolicy(sizePolicy)
self.progressBar.setProperty("value", 0)
self.progressBar.setObjectName(_fromUtf8("progressBar"))
self.horizontalLayout_2.addWidget(self.progressBar)
self.gridLayout_3.addLayout(self.horizontalLayout_2, 1, 0, 1, 3)
self.verticalLayout_2 = QtGui.QVBoxLayout()
self.verticalLayout_2.setObjectName(_fromUtf8("verticalLayout_2"))
self.radioButton_2 = QtGui.QRadioButton(self.centralwidget)
self.radioButton_2.setObjectName(_fromUtf8("radioButton_2"))
self.verticalLayout_2.addWidget(self.radioButton_2)
self.radioButton = QtGui.QRadioButton(self.centralwidget)
self.radioButton.setObjectName(_fromUtf8("radioButton"))
self.verticalLayout_2.addWidget(self.radioButton)
self.gridLayout_3.addLayout(self.verticalLayout_2, 2, 0, 1, 1)
self.gridLayout_2 = QtGui.QGridLayout()
self.gridLayout_2.setObjectName(_fromUtf8("gridLayout_2"))
self.label = QtGui.QLabel(self.centralwidget)
self.label.setObjectName(_fromUtf8("label"))
self.gridLayout_2.addWidget(self.label, 0, 0, 1, 1)
self.label_2 = QtGui.QLabel(self.centralwidget)
self.label_2.setObjectName(_fromUtf8("label_2"))
self.gridLayout_2.addWidget(self.label_2, 0, 1, 1, 1)
self.label_3 = QtGui.QLabel(self.centralwidget)
self.label_3.setObjectName(_fromUtf8("label_3"))
self.gridLayout_2.addWidget(self.label_3, 0, 2, 1, 1)
self.spinBox = QtGui.QSpinBox(self.centralwidget)
self.spinBox.setObjectName(_fromUtf8("spinBox"))
self.gridLayout_2.addWidget(self.spinBox, 1, 0, 1, 1)
self.spinBox_2 = QtGui.QSpinBox(self.centralwidget)
self.spinBox_2.setObjectName(_fromUtf8("spinBox_2"))
self.gridLayout_2.addWidget(self.spinBox_2, 1, 1, 1, 1)
self.spinBox_3 = QtGui.QSpinBox(self.centralwidget)
self.spinBox_3.setObjectName(_fromUtf8("spinBox_3"))
self.gridLayout_2.addWidget(self.spinBox_3, 1, 2, 1, 1)
self.gridLayout_3.addLayout(self.gridLayout_2, 2, 1, 1, 2)
self.label_4 = QtGui.QLabel(self.centralwidget)
self.label_4.setObjectName(_fromUtf8("label_4"))
self.gridLayout_3.addWidget(self.label_4, 3, 0, 1, 1)
self.pushButton = QtGui.QPushButton(self.centralwidget)
self.pushButton.setObjectName(_fromUtf8("pushButton"))
self.gridLayout_3.addWidget(self.pushButton, 3, 1, 1, 1)
self.pushButton_2 = QtGui.QPushButton(self.centralwidget)
self.pushButton_2.setObjectName(_fromUtf8("pushButton_2"))
self.gridLayout_3.addWidget(self.pushButton_2, 3, 2, 1, 1)
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtGui.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 1024, 25))
self.menubar.setObjectName(_fromUtf8("menubar"))
MainWindow.setMenuBar(self.menubar)
self.statusbar = QtGui.QStatusBar(MainWindow)
self.statusbar.setObjectName(_fromUtf8("statusbar"))
MainWindow.setStatusBar(self.statusbar)
self.pushButton.setCheckable(True)
self.pushButton.pressed.connect(self.start_watch)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
MainWindow.setWindowTitle(_translate("MainWindow", "Time_it!", None))
self.radioButton_2.setText(_translate("MainWindow", "Counter", None))
self.radioButton.setText(_translate("MainWindow", "Countdown", None))
self.label.setText(_translate("MainWindow", "hr", None))
self.label_2.setText(_translate("MainWindow", "min", None))
self.label_3.setText(_translate("MainWindow", "sec", None))
self.label_4.setText(_translate("MainWindow", "martin.bednar@hotmail.sk", None))
self.pushButton.setText(_translate("MainWindow", "Start", None))
self.pushButton_2.setText(_translate("MainWindow", "Stop", None))
def start_watch(self,pressed = True):
if(pressed):
hrs = ui.spinBox.value()
minutes = ui.spinBox_2.value()
second = ui.spinBox_3.value()
timeings=time_format_deconverter([hrs,minutes,second])
global watch
watch = Watch(type="Countdown", seconds = timeings)
QObject.connect(watch.drawer,SIGNAL("asignal"),watch.drawer.connected_from_main_thread,Qt.QueuedConnection)
watch.watch.run_me()
def time_format_converter(number): #99hours * 60 *60 *10 + 59minutes*60 *10 + 59seconds*10 + 9seconds/10
if(number>3599999):
return 8,8,8,8,8,8,8
else:
hours_1 = number//36000//10
hours_2 = number//36000%10
number = number - hours_1*360000 - hours_2*36000
minutes_1 = number//600//10
minutes_2 = number//600%10
if(minutes_1>=6):
minutes_1 = minutes_1 - 6
if(hours_2!=9):
hours_2 = hours_2 + 1
if(hours_2==9):
hours_2 = 0
hours_1 = hours_1 + 1
number = number - minutes_1*600 - minutes_2*600
seconds_1 = number//10//10
seconds_2 = number//10%10
seconds_10 = number%10
if(seconds_1>=6):
seconds_1 = seconds_1 - 6
if(minutes_2!=9):
minutes_2 = minutes_2 + 1
if(minutes_2==9):
minutes_2 = 0
minutes_1 = minutes_1 + 1
return hours_1, hours_2, minutes_1, minutes_2, seconds_1, seconds_2, seconds_10
def time_format_deconverter(data):
'''
input [HR,MIN,SEC]
output [SEC * 10]
'''
return data[0]* 36000 + data[1] * 600 + data[2] * 10
watch = 0 #create global object named watch
if __name__ == "__main__":
import sys
app = QtGui.QApplication(sys.argv)
MainWindow = QtGui.QMainWindow()
ui = Ui_MainWindow()
ui.setupUi(MainWindow)
MainWindow.show()
sys.exit(app.exec_())
【问题讨论】:
这可能是问题***.com/questions/1595649/… 【参考方案1】:您不能直接从另一个线程访问 gui 线程。没有理由在这样的简单计时器中使用线程。使用QTimer
每秒“打勾”更新ui,通过QTime
或python的time
模块获取当前时间。
【讨论】:
以上是关于Python中的冻结Qt GUI的主要内容,如果未能解决你的问题,请参考以下文章
QT QThread::isrunning 冻结程序在 Pi
使用 Fbs/PyInstaller 冻结我的应用程序导致在另一台电脑上启动时无法执行 pyi_rth_qt5plugins