1
votes

I am working with python 2.7 I am getting some multi threading problems with pyqt

I am trying to read a sqlite file, and import its content into the main GUI of application.

So what I do I created a Thread class

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()"))

And When user click in menubar to open SQlite file, a function is called, a instance of that thread class is created and the thread is called.

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()

And in this sqlOpen() method, I accessed the rows of sqlite and placed the data in few QLabels,self.ui is my object of my mainWindow GUI(which contains, retranslate,setupUi etc etc functions)

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()

but after thread execution, my whole application crashes after echoing this errors.

QObject::setParent: Cannot set parent, new parent is in a different thread

QObject::setParent: Cannot set parent, new parent is in a different thread

QObject: Cannot create children for a parent that is in a different thread.

(Parent is QLabel(0x3315318), parent's thread is QThread(0x288fa78), current thr ead is Thread_OpenSqlite(0x358e3a8)

QObject: Cannot create children for a parent that is in a different thread. (Parent is QTextDocument(0x367d728), parent's thread is Thread_OpenSqlite(0x358e 3a8), current thread is QThread(0x288fa78)

I have read multiple pyqt thread and previous questions, and they have in common to say that

Elements of GUI in main thread cannot be modified in run method itself, so you have to use signals and slot mechanism to emit the signal and connect it to a slot which will do the job.

Note I have also tried QueuedConnection in place of DirectConnection, although it fixed my problem but on exiting the application, it displays the Crashing popup of python, which I dont wan't

I have also done various multithreading operations in same application to put and get data from GUI elements but this is the only one bugging me.

Can anyone tell me where I am getting wrong above?

Thanks in Advance.

1

1 Answers

0
votes

It looks like your threading code is just raising a signal to run open_sqlite, which will just get run in the main thread anyway. Also, it doesn't seem like you need to thread this. If you are just filling labels (and not something like a table), then your data is not very dynamic, so you likely don't need to run it in a thread. Just run it in the main thread as part of initialization of your program or in reaction to an event. Avoid multithreading whenever possible; it is notoriously easy to break something (in any language or framework).

If you must, then use a threadpool (either python native, or Qt based) and then poll the pool in the event loop until the work is done. Workpools are a lot more safe and easy to debug and reason about.