2015-10-17 67 views
0

我与Python 2.7 我得到与PyQt的一些多线程问题共创儿童PyQt的多线程,不能为父母

我想读一个sqlite的文件,并导入其内容进入主界面的应用程序。

所以我做什么我创建了一个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()方法,我访问源码的行和放置在数据在几个QLabels,self.ui是我的我的主窗口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 EAD是Thread_OpenSqlite(0x358e3a8)

QObject的:不能对父母说是在不同的线程创建儿童 (父被另外,QTextDocument(0x367d728),父母的线程是Thread_OpenSqlite(0x358e 3A8),当前线程的QThread(0x288fa78)

我已阅读多个PyQt的线程和前面的问题,他们有共同的说,

在主线程中GUI的元素无法在运行方法本身中修改,因此您必须使用信号和插槽机制来发出信号并将其连接到将执行此任务的插槽。

注意 我也曾尝试QueuedConnection到位DirectConnection,虽然它固定我的问题,但在退出应用程序,它显示蟒崩溃弹出,这是我不wan't

我也在同一个应用程序中完成了各种多线程操作,以便从GUI元素中获取数据,但这是唯一一个让我烦恼的人。

任何人都可以告诉我在哪里我错了吗?

在此先感谢。

回答

0

它看起来像你的线程代码只是提高信号运行open_sqlite,它只会在主线程中运行。此外,它似乎并不像你需要线程这一点。如果你只是填充标签(而不是表格),那么你的数据不是很动态的,所以你可能不需要在一个线程中运行它。只需在主线程中运行它,作为程序初始化的一部分或者对事件的反应。尽可能避免多线程;以任何语言或框架来破解某些东西是非常容易的。

如果必须的话,然后使用线程池(python native或Qt based),然后在事件循环中轮询池直到完成工作。 Workpools更安全,易于调试和推理。

+0

我以后填表的时候,差不多像是40000行,那就是为什么我需要线程来让我的主GUI不挂断。稍后我会看看线程池。 – user3475900

+1

您可以改为查看[QSqlTableModel](https://srinikom.github.io/pyside-docs/PySide/QtSql/QSqlTableModel.html)(它具有对sqlite的本地支持)并使用Mode-View-Controller解决这个问题的范式。它只会根据需要从数据库中获取所需的内容,而且不会增加线程的复杂性。我仍然可以在init或根据事件填写标签。使用上面的内置类,您可以获得活泼的实时性能,并且永远不需要处理线程的头痛问题(这会让您占用很长时间,我可以承诺)。 – eestrada