我正在使用python 2.7 我在使用pyqt
时遇到了一些多线程问题我正在尝试读取sqlite文件,并将其内容导入应用程序的主GUI。
所以我做了什么,我创建了一个Thread类
class Thread_OpenSqlite(QtCore.QThread):
def __init__(self,parent=None):
super(Thread_OpenSqlite,self).__init__(parent)
def run(self):
self.emit(QtCore.SIGNAL("open_sqlite()"))
当用户点击菜单栏打开SQlite文件时,会调用一个函数,创建该线程类的实例并调用该线程。
def selectSQLite(self):
self.typeflag=4
self.openpath=QFileDialog.getOpenFileName()
if os.path.exists(str(self.openpath)):
#Thread to Open Sqlite
self.threadopenSqlite=Thread_OpenSqlite()
self.connect(self.threadopenSqlite, QtCore.SIGNAL("open_sqlite()"), self.sqlOpen, QtCore.Qt.DirectConnection)
self.threadopenSqlite.start()
在这个sqlOpen()方法中,我访问了sqlite的行并将数据放在少量QLabel中, self.ui 是我的mainWindow GUI的对象(包含,重新翻译,setupUi等)等功能)
def sqlOpen(self):
conn = sqlite3.connect(str(self.openpath))
print self.openpath
cursor = conn.cursor()
try:
abc=cursor.execute('select some,rows,of,sqlite,to,read,from from general_info limit 0,1')
for row in abc:
self.ui.pushButton_2.show()
self.ui.pushButton_2.setText(str(row[6]))
self.ui.lineEdit.show()
self.ui.pushButton_9.show()
self.ui.label_2.setText(str(row[0]))
self.ui.label_9.setText(str(row[1]))
self.ui.label_10.setText(str(row[2]))
self.ui.label_11.setText(str(row[3]))
self.ui.label_12.setText(str(row[4]))
self.ui.label_13.setText(str(row[5]))
self.ui.label_14.setText(str(row[6]))
self.ui.label_15.setText(str(row[7]))
conn.close()
except sqlite3.OperationalError:
conn.close()
但在执行线程后,我的整个应用程序在回显此错误后崩溃。
QObject :: setParent:无法设置父级,新父级位于不同的线程
QObject :: setParent:无法设置父级,新父级位于不同的线程
QObject:无法为位于不同线程中的父级创建子级。
(Parent是QLabel(0x3315318),父亲的线程是QThread(0x288fa78),当前thr是线程_OpenSqlite(0x358e3a8)
QObject:无法为不同线程中的父级创建子级。 (Parent是QTextDocument(0x367d728),父级的线程是Thread_OpenSqlite(0x358e) 3a8),当前线程是QThread(0x288fa78)
我已经读过多个pyqt线程和之前的问题,他们有共同的说法
主线程中GUI的元素不能在run方法本身中修改,因此你必须使用信号和插槽机制发出信号并将其连接到一个可以完成工作的插槽。
注意 我也试过 QueuedConnection 代替DirectConnection,虽然它解决了我的问题,但在退出应用程序时,它显示了python的崩溃弹出窗口,我不想 < / p>
我还在同一个应用程序中完成了各种多线程操作,从GUI元素中获取和获取数据,但这是唯一一个困扰我的人。
有谁能告诉我上面哪里出错了?
先谢谢。
答案 0 :(得分:0)
看起来你的线程代码只是提出一个运行open_sqlite
的信号,它只会在主线程中运行。此外,它似乎不需要解决这个问题。如果您只是填充标签(而不是表格),那么您的数据不是非常动态,因此您可能不需要在线程中运行它。只需在主线程中运行它作为程序初始化的一部分或响应事件。尽可能避免多线程;打破某些东西(任何语言或框架)都是非常容易的。
如果必须,则使用线程池(python本机或基于Qt),然后在事件循环中轮询池,直到工作完成。工作池更加安全,易于调试和推理。