2015-10-17 81 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