我编写了简单的python脚本,但我遇到了问题。我想运行一个没有被阻止的GUI(使用过的线程)的函数,并且该函数有多个线程。最后它产生了2种错误。第一个是
QObject::connect: Cannot queue arguments of type 'QTextCursor' (Make sure 'QTextCursor' is registered using qRegisterMetaType().)
第二个是
Segmentation fault (core dumped)
我的脚本无法找到错误。出了什么问题?
form.py
from PyQt4 import QtCore, QtGui
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(956, 395)
self.centralwidget = QtGui.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.horizontalLayoutWidget = QtGui.QWidget(self.centralwidget)
self.horizontalLayoutWidget.setGeometry(QtCore.QRect(230, 30, 716, 251))
self.horizontalLayoutWidget.setObjectName("horizontalLayoutWidget")
self.horizontalLayout = QtGui.QHBoxLayout(self.horizontalLayoutWidget)
self.horizontalLayout.setObjectName("horizontalLayout")
self.textEdit_2 = QtGui.QTextEdit(self.horizontalLayoutWidget)
self.textEdit_2.setObjectName("textEdit_2")
self.horizontalLayout.addWidget(self.textEdit_2)
self.textEdit_3 = QtGui.QTextEdit(self.horizontalLayoutWidget)
self.textEdit_3.setObjectName("textEdit_3")
self.horizontalLayout.addWidget(self.textEdit_3)
self.textEdit_4 = QtGui.QTextEdit(self.horizontalLayoutWidget)
self.textEdit_4.setObjectName("textEdit_4")
self.horizontalLayout.addWidget(self.textEdit_4)
self.textEdit_5 = QtGui.QTextEdit(self.horizontalLayoutWidget)
self.textEdit_5.setObjectName("textEdit_5")
self.horizontalLayout.addWidget(self.textEdit_5)
self.textEdit_6 = QtGui.QTextEdit(self.horizontalLayoutWidget)
self.textEdit_6.setObjectName("textEdit_6")
self.horizontalLayout.addWidget(self.textEdit_6)
self.textEdit_7 = QtGui.QTextEdit(self.horizontalLayoutWidget)
self.textEdit_7.setObjectName("textEdit_7")
self.horizontalLayout.addWidget(self.textEdit_7)
self.textEdit_8 = QtGui.QTextEdit(self.horizontalLayoutWidget)
self.textEdit_8.setObjectName("textEdit_8")
self.horizontalLayout.addWidget(self.textEdit_8)
self.textEdit_9 = QtGui.QTextEdit(self.horizontalLayoutWidget)
self.textEdit_9.setObjectName("textEdit_9")
self.horizontalLayout.addWidget(self.textEdit_9)
self.table = QtGui.QTableWidget(self.centralwidget)
self.table.setGeometry(QtCore.QRect(10, 30, 211, 291))
self.table.setObjectName("table")
self.table.setColumnCount(2)
self.table.setRowCount(0)
item = QtGui.QTableWidgetItem()
self.table.setHorizontalHeaderItem(0, item)
item = QtGui.QTableWidgetItem()
self.table.setHorizontalHeaderItem(1, item)
self.button = QtGui.QPushButton(self.centralwidget)
self.button.setGeometry(QtCore.QRect(120, 330, 85, 27))
self.button.setObjectName("button")
self.button_2 = QtGui.QPushButton(self.centralwidget)
self.button_2.setGeometry(QtCore.QRect(10, 330, 85, 27))
self.button_2.setObjectName("button_2")
self.log = QtGui.QTextEdit(self.centralwidget)
self.log.setGeometry(QtCore.QRect(230, 290, 361, 71))
self.log.setObjectName("log")
MainWindow.setCentralWidget(self.centralwidget)
self.statusbar = QtGui.QStatusBar(MainWindow)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)
self.retranslateUi(MainWindow)
QtCore.QObject.connect(self.button_2, QtCore.SIGNAL("clicked()"), MainWindow.close)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
MainWindow.setWindowTitle(QtGui.QApplication.translate("MainWindow", "MainWindow", None, QtGui.QApplication.UnicodeUTF8))
self.table.horizontalHeaderItem(0).setText(QtGui.QApplication.translate("MainWindow", "no", None, QtGui.QApplication.UnicodeUTF8))
self.table.horizontalHeaderItem(1).setText(QtGui.QApplication.translate("MainWindow", "status", None, QtGui.QApplication.UnicodeUTF8))
self.button.setText(QtGui.QApplication.translate("MainWindow", "Run", None, QtGui.QApplication.UnicodeUTF8))
self.button_2.setText(QtGui.QApplication.translate("MainWindow", "Close", None, QtGui.QApplication.UnicodeUTF8))
main.py
from form import *
import time
import threading
import os
from subprocess import call
import Queue
class mainWindow(QtGui.QMainWindow):
def __init__(self, parent=None):
QtGui.QWidget.__init__(self,parent)
self.ui = Ui_MainWindow()
self.ui.setupUi(self)
self.ui.table.verticalHeader().setVisible(False)
for i in range(2,10):
item = QtGui.QTableWidgetItem(str(i))
item2 = QtGui.QTableWidgetItem("Ready")
item.setFlags(QtCore.Qt.ItemIsUserCheckable | QtCore.Qt.ItemIsEnabled)
item.setCheckState(QtCore.Qt.Unchecked)
self.ui.table.setRowCount(i-1)
self.ui.table.setItem(i-2, 0, item)
self.ui.table.setItem(i-2, 1, item2)
#:for
QtCore.QObject.connect(self.ui.button , QtCore.SIGNAL("clicked()"), self.callback_runButton)
#:def
def callback_runButton(self):
numList = []
for i in range(0,self.ui.table.rowCount()):
if self.ui.table.item(i,0).checkState() == 2 and str(self.ui.table.item(i,1).text()) == 'Ready':
print self.ui.table.item(i,0).text()
self.ui.table.item(i,1).setText('Run')
numList.append(i)
#if
#:for
#### Question 1:
#1. I want to no blocking GUI under runnig "self.run_MultiplicationTable(numList)"
#2. although called "self.run_MultiplicationTable(numList)", I Want to run function again.
#3. I try to thread function. but #2 is not permit. (GUI is not blocking, but function is not excuted.)
#4. I try to process(run fuction under child process), but I can't modify GUI(parent process).
#self.run_MultiplicationTable(numList)
th = Run_MultiplicationTable(self,numList)
th.start()
#:def
def run_MultiplicationTable(self, numList):
print "Run_MultiplicationTable"
for i in numList:
#### Question 2: smilay Question 1
#1. I want to run under function at same time.
self.each_Cal(i)
#:for
#def
def each_Cal(self, num):
i = self.ui.table.item(num,0).text()
putTextEdit = eval('self.ui.textEdit_'+ str(i))
for j in range(1,10):
printString = str(i)+' * '+str(j)+'='+str(int(i)*j)
putTextEdit.append(printString)
time.sleep(1) #It is job excuted time
#:for
self.ui.table.item(num,1).setText('Done')
#def
#:class
class Run_MultiplicationTable(threading.Thread):
def __init__(self, mainWin,numList ,daemon=True, parent=None ):
threading.Thread.__init__(self)
self.mainWin = mainWin
self.daemon = daemon
self.numList = numList
#def
def run(self):
thList = []
for num in self.numList:
q = Queue.Queue()
th2 = Run_Each(self.mainWin, num,q)
th2.start()
thList.append([q,th2])
#:for
#Check close of all sub-thread.
while True:
isRun = False
for i in thList:
print str(i[1])+' '+str(i[1].is_alive())
isRun = isRun or i[1].is_alive()
if i[1].is_alive() :
getVal = i[0].get()
print "End 1ea sub Class"
#if
#for
if not isRun:
break
#while
print "END " + str(self)
#def
#class
class Run_Each(threading.Thread):
def __init__(self, mainWin,num ,q,daemon=True, parent=None ):
threading.Thread.__init__(self)
self.mainWin = mainWin
self.daemon = daemon
self.num = num
self.q = q
#def
def run(self):
i = self.mainWin.ui.table.item(self.num,0).text()
self.mainWin.ui.log.append("Run_MultiplicationTable:"+i)
putTextEdit = eval('self.mainWin.ui.textEdit_'+ str(i))
for j in range(1,10):
printString = str(i)+' * '+str(j)+'='+str(int(i)*j)
putTextEdit.append(printString)
#time.sleep(1) #It is job excuted time
#:for
self.mainWin.ui.table.item(self.num,1).setText('Ready')
self.q.put(True)
#def
#class
if __name__ == "__main__":
import sys
app = QtGui.QApplication(sys.argv)
MainWin = mainWindow()
MainWin.show()
sys.exit(app.exec_())
答案 0 :(得分:0)
您不能直接从线程修改GUI。这是您的分段错误的原因(并且您的连接问题可能是由于您尝试跨线程执行操作)
相反,您需要使用QThread
(而不是Python线程库)并从QThread
向主线程中的插槽发出信号,将任何必要的数据传递到插槽,这样插槽可以从主线程更新GUI。