Python PyQt多线程,无法为父级创建子级

Python PyQt多线程,无法为父级创建子级,python,multithreading,pyqt,Python,Multithreading,Pyqt,我正在使用python 2.7 我在pyqt上遇到了一些多线程问题 我试图读取一个sqlite文件,并将其内容导入到应用程序的主GUI中 所以我创建了一个线程类 class Thread_OpenSqlite(QtCore.QThread): def __init__(self,parent=None): super(Thread_OpenSqlite,self).__init__(parent) def run(self): self.

我正在使用python 2.7 我在pyqt上遇到了一些多线程问题

我试图读取一个sqlite文件,并将其内容导入到应用程序的主GUI中

所以我创建了一个线程类

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是我的主窗口GUI的对象(它包含、重传、setupUi等函数)

但是在线程执行之后,我的整个应用程序在回显这个错误后崩溃

QObject::setParent:无法设置父级,新父级位于其他线程中

QObject::setParent:无法设置父级,新父级位于其他线程中

QObject:无法为位于不同线程中的父线程创建子线程

(父线程是QLabel(0x3315318),父线程是QThread(0x288fa78),当前线程头是thread_OpenSqlite(0x358e3a8)

QObject:无法为位于不同线程中的父线程创建子线程。 (父线程是QTextDocument(0x367d728),父线程是thread_OpenSqlite(0x358e) 3a8),当前线程为QThread(0x288fa78)

我读过多个pyqt线程和前面的问题,他们都这么说

主线程中的GUI元素不能在run方法本身中修改,所以您必须使用信号和插槽机制来发出信号,并将其连接到一个将执行此任务的插槽

注意 我还尝试了QueuedConnection来代替DirectConnection,虽然它解决了我的问题,但在退出应用程序时,它会显示python的崩溃弹出窗口,我不想这样做

我还在同一个应用程序中执行了各种多线程操作,以从GUI元素中放置和获取数据,但这是唯一一个让我感到不安的地方

谁能告诉我上面哪里出了问题


提前感谢。

看起来你的线程代码只是发出了一个运行
open_sqlite
的信号,它将在主线程中运行。而且,你似乎不需要执行此任务。如果你只是填充标签(而不是像表格一样的东西),则您的数据不是非常动态的,因此您可能不需要在线程中运行它。只需在主线程中运行它,作为程序初始化的一部分或作为对事件的反应。尽可能避免多线程;众所周知,在任何语言或框架中都很容易破坏某些内容


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

看起来线程代码只是发出了一个运行
open\u sqlite
的信号,它将在主线程中运行。此外,似乎不需要对其执行线程。如果您只是填充标签(而不是像表格一样),则数据不是非常动态的,因此您可能不需要在线程中运行它。只需在主线程中运行它,作为程序初始化的一部分或作为对事件的反应。尽可能避免多线程;众所周知,破坏某些内容(在任何语言或框架中)都很容易


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

我稍后会填充表格,几乎是40000行,这就是为什么我需要线程,以便我的主gui不会挂起。稍后我将查看线程池。您可能想查看(具有对sqlite的本机支持)并使用模式-视图-控制器范例来解决这个问题。它只会根据需要从数据库中获取所需的内容,同样,也不需要增加线程的复杂性。我仍然会在init或基于事件填充标签。使用上述内置类,您可以获得快速的实时性能,而无需处理headach线程(我可以保证,这会让您占用相当长的一段时间)。稍后我会填充表格,几乎有40000行,这就是为什么我需要线程,以便我的主gui不会挂断。稍后我将查看线程池。您可能想查看(它具有对sqlite的本机支持)并使用模式-视图-控制器范例来解决这个问题。它只会根据需要从数据库中获取所需的内容,同样,也不需要增加线程的复杂性。我仍然会在init或基于事件填充标签。使用上述内置类,您可以获得快速的实时性能,而无需处理headach线程的e(我可以保证,这会让您占用相当长的一段时间)。
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()