如何从另一个python文件调用Qt线程(QThread)?(QThread已销毁)
我应该如何调用另一个python文件中定义的如何从另一个python文件调用Qt线程(QThread)?(QThread已销毁),python,python-2.7,pyqt,pyqt4,qthread,Python,Python 2.7,Pyqt,Pyqt4,Qthread,我应该如何调用另一个python文件中定义的QThread 这是我的密码 mymain.py from PyQt4 import QtCore, QtGui import PyQt4 import sys import os from time import sleep try: _fromUtf8 = QtCore.QString.fromUtf8 except AttributeError: _ fromUtf8 = lambda s: s class Ui_MainWin
QThread
这是我的密码
mymain.py
from PyQt4 import QtCore, QtGui
import PyQt4
import sys
import os
from time import sleep
try:
_fromUtf8 = QtCore.QString.fromUtf8
except AttributeError:
_ fromUtf8 = lambda s: s
class Ui_MainWindow(QtGui.QMainWindow):
def __init__(self):
QtGui.QWidget.__init__(self)
self.setupUi(self)
def setupUi(self, MainWindow):
MainWindow.setObjectName(_fromUtf8("MainWindow"))
self.showMaximized()
MainWindow.setStyleSheet(_fromUtf8("background-color: rgb(0, 0, 0);"))
self.centralwidget = QtGui.QWidget(MainWindow)
self.centralwidget.setObjectName(_fromUtf8("centralwidget"))
self.horizontalLayout = QtGui.QHBoxLayout(self.centralwidget)
self.horizontalLayout.setObjectName(_fromUtf8("horizontalLayout"))
self.gridLayout = QtGui.QGridLayout()
self.gridLayout.setObjectName(_fromUtf8("gridLayout"))
spacerItem = QtGui.QSpacerItem(20, 40, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding)
self.gridLayout.addItem(spacerItem, 2, 0, 1, 1)
self.horizontalLayout_2 = QtGui.QHBoxLayout()
self.horizontalLayout_2.setObjectName(_fromUtf8("horizontalLayout_2"))
self.verticalLayout = QtGui.QVBoxLayout()
self.verticalLayout.setObjectName(_fromUtf8("verticalLayout"))
self.lblNowServing = QtGui.QLabel(self.centralwidget)
font = QtGui.QFont()
font.setFamily(_fromUtf8("Bebas Neue"))
font.setPointSize(140)
self.lblNowServing.setFont(font)
self.lblNowServing.setStyleSheet(_fromUtf8("color: rgb(170, 0, 0);"))
self.lblNowServing.setObjectName(_fromUtf8("lblNowServing"))
self.lblNowServing.setAlignment(QtCore.Qt.AlignCenter)
self.verticalLayout.addWidget(self.lblNowServing)
self.lblNowServingNumber = QtGui.QLabel(self.centralwidget)
font = QtGui.QFont()
font.setFamily(_fromUtf8("DS-Digital"))
font.setPointSize(350)
self.lblNowServingNumber.setFont(font)
self.lblNowServingNumber.setStyleSheet(_fromUtf8("color: rgb(170, 0, 0);"))
self.lblNowServingNumber.setObjectName(_fromUtf8("lblNowServingNumber"))
self.lblNowServingNumber.setAlignment(QtCore.Qt.AlignCenter)
self.verticalLayout.addWidget(self.lblNowServingNumber)
self.horizontalLayout_2.addLayout(self.verticalLayout)
self.verticalLayout_2 = QtGui.QVBoxLayout()
self.verticalLayout_2.setObjectName(_fromUtf8("verticalLayout_2"))
self.lblCounter = QtGui.QLabel(self.centralwidget)
font = QtGui.QFont()
font.setFamily(_fromUtf8("Bebas Neue"))
font.setPointSize(140)
self.lblCounter.setFont(font)
self.lblCounter.setStyleSheet(_fromUtf8("color: rgb(170, 0, 0);"))
self.lblCounter.setObjectName(_fromUtf8("lblCounter"))
self.lblCounter.setAlignment(QtCore.Qt.AlignCenter)
self.verticalLayout_2.addWidget(self.lblCounter)
self.lblCounterNumber = QtGui.QLabel(self.centralwidget)
font = QtGui.QFont()
font.setFamily(_fromUtf8("DS-Digital"))
font.setPointSize(350)
self.lblCounterNumber.setFont(font)
self.lblCounterNumber.setStyleSheet(_fromUtf8("color: rgb(170, 0, 0);"))
self.lblCounterNumber.setObjectName(_fromUtf8("lblCounterNumber"))
self.lblCounterNumber.setAlignment(QtCore.Qt.AlignCenter)
self.verticalLayout_2.addWidget(self.lblCounterNumber)
self.horizontalLayout_2.addLayout(self.verticalLayout_2)
self.gridLayout.addLayout(self.horizontalLayout_2, 0, 0, 1, 1)
spacerItem = QtGui.QSpacerItem(20, 40, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding)
self.gridLayout.addItem(spacerItem, 1, 0, 1, 1)
self.horizontalLayout.addLayout(self.gridLayout)
MainWindow.setCentralWidget(self.centralwidget)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
MainWindow.setWindowTitle(QtGui.QApplication.translate("MainWindow", "MainWindow", None, QtGui.QApplication.UnicodeUTF8))
self.lblNowServing.setText(QtGui.QApplication.translate("MainWindow", " NOW SERVING ", None, QtGui.QApplication.UnicodeUTF8))
self.lblCounter.setText(QtGui.QApplication.translate("MainWindow", "COUNTER", None, QtGui.QApplication.UnicodeUTF8))
self.lblCounterNumber.setText(str(1))
self.lblNowServingNumber.setText(str(1))
class valChange(QtCore.QThread):
def __init__(self):
QtCore.QThread.__init__(self)
def run(self):
self.myctr = 0
self.myval = 0
self.lblNowServingNumber.setText(str(myval))
self.lblCounterNumber.setText(str(myctr))
if __name__=='__main__':
app = QtGui.QApplication(sys.argv)
ex = Ui_MainWindow()
ex.show()
sys.exit(app.exec_())
exarg.py
from PyQt4 import QtCore, QtGui
import mymain
import sys, getopt
def main(argv):
ctr = ''
val = ''
try:
opts, args = getopt.getopt(argv,"hi:o:",["ifile=","ofile="])
except getopt.GetoptError:
print 'test.py -i <ctr> -o <val>'
sys.exit(2)
for opt, arg in opts:
if opt == '-h':
print 'test.py -i <ctr> -o <val>'
sys.exit()
elif opt in ("-i", "--ifile"):
ctr = arg
elif opt in ("-o", "--ofile"):
val = arg
m = mymain.valChange()
m.myctr = ctr
m.myval = val
m.start()
if __name__ == "__main__":
app = QtGui.QApplication(sys.argv)
main(sys.argv[1:])
从PyQt4导入QtCore,QtGui
导入mymain
导入sys,getopt
def总管(argv):
ctr=“”
val=''
尝试:
opts,args=getopt.getopt(argv,“hi:o:”,[“ifile=”,“ofile=”)
除getopt.GetoptError外:
打印“test.py-i-o”
系统出口(2)
对于opt,opt中的参数:
如果opt='-h':
打印“test.py-i-o”
sys.exit()
elif选择加入(“-i”、“ifile”):
ctr=arg
elif选择加入(“-o”和“-ofile”):
val=arg
m=mymain.valChange()
m、 myctr=ctr
m、 myval=val
m、 开始()
如果名称=“\uuuuu main\uuuuuuuu”:
app=QtGui.QApplication(sys.argv)
main(sys.argv[1:])
这就是我所做的,我在shell中运行mymain.py。我使用这个命令在终端/命令行中运行exarg.py
sudopython exarg.py-i3-o4
但我总是会犯这样一个错误:
'QThread:在线程仍在运行时销毁'
如有任何意见/建议,将不胜感激。谢谢。您的代码目前存在一些问题 首先,您似乎不会在任何地方调用
app.exec()
(至少在运行exarg.py
时)来实际启动QApplication
。但也许你只是忘了把它包括进去
第二,在函数中创建线程,并将其分配给变量m
。函数main
一结束,该局部变量就会被垃圾收集,线程就会被销毁。你需要确保这不会发生。通过使m
成为全局变量,或从函数返回m
,并保留对它的引用,或无法在函数内部创建它。只要您始终持有对线程的引用,它就不会被销毁,您也不会看到错误消息
最后,您应该不要直接从线程修改GUI对象。Qt小部件不是线程安全的!您需要做的是在线程中定义一个信号,并在创建线程时将插槽(从主线程)连接到该信号。然后,您可以从线程发出一个信号(这是线程安全的),该信号将调用主线程中允许您修改GUI的插槽。问题/答案大致说明了如何做到这一点
编辑:此外,全局myctr
等代码令人困惑。你不应该需要那个。在调用m.start()
之前,只需从线程内以self.myctr
的身份访问它们,因为您已经编写了m.myctr=ctr
,我觉得这与您的原始代码相比已经被削减得太多了。线程中有未定义的变量。更不用说,看起来您正试图直接从线程修改GUI(这不是一个好主意,除非您喜欢随机崩溃!)。我更新了mymain.py,以便您可以查看完整代码。是的,我正在尝试使用QThread修改Gui中的Qlabel。有什么建议吗?