I am using PyQT5 to create a GUI app. The GUI app process needs to run two threads consecutively to work. Thread #1 to run the MainWindow App and the Thread #2 (Emitter) to monitor for any incoming signals or changes to the MainWindow.
MainWindow (#1 Thread):
class MainWindow(QMainWindow, Ui_MainWindow):
def __init__(self, queue_from_mother: Queue, queue_to_mother: Queue, emitter: Emitter):
QMainWindow.__init__(self)
self.queue_from_mother = queue_from_mother
self.queue_to_mother = queue_to_mother
self.emitter = emitter
self.emitter.daemon = True
self.emitter.start()
# Much more code, but irrelevant
Emitter (#2 thread):
class Emitter(QThread):
def __init__(self, from_process: Pipe, queue_to_mother: Queue, queue_from_mother: Queue):
super().__init__()
def run(self):
while True:
GUIcmds = <list>ReadMemorySpace() # a C external Function to read from Shared memory space and return a Python object
if("change" in GUIcmds)
self.somelbl.emit("GUIcmds")
cdef public void mainSec():
app = QtWidgets.QApplication(sys.argv)
emitter = mdx.Emitter(mother_pipe, queue_to_mother, queue_from_mother)
Dialog = mdx.MainWindow(queue_from_mother, queue_to_mother, emitter)
Dialog.show()
sys.exit(app.exec_())
Pure External C:
#include "mdx.h"
int main(){
program = Py_DecodeLocale(argv[0], NULL);
if (program == NULL) {
fprintf(stderr, "Fatal error: cannot decode argv[0], got %d arguments\n", argc);
exit(1);
}
//PyImport_AppendInittab("mdx", PyInit_mdx);
if (PyImport_AppendInittab("commonmodules", PyInit_mdx) == -1) {
fprintf(stderr, "Error: could not extend in-built modules table\n");
exit(1);
}
Py_SetProgramName(program);
Py_Initialize();
pmodule = PyImport_ImportModule("mdx");
if (!pmodule) {
PyErr_Print();
fprintf(stderr, "Error: could not import module 'embedded'\n");
return -1;
}
PyObject* sys = PyImport_ImportModule("sys");
PyObject* path = PyObject_GetAttrString(sys, "path");
PyList_Append(path, PyUnicode_FromString("."));
PyList_Append(path, PyUnicode_FromString("C:/Users/uesrname/AppData/Local/Programs/Python/python39/"));
/* 1st: Import the module */
PyObject* ModuleString = PyUnicode_FromString((char*)"mdx");
if (!ModuleString) {
PyErr_Print();
printf("Error formating python script\n");
}
PyObject* Module = PyImport_Import(ModuleString);
if (!Module) {
PyErr_Print();
printf("Error importing python script\n");
}
__pyx_f_13commonmodules_mainSec();
Py_Finalize();
}
Note: since the code is too much, I am providing only the sections relevant to the question.
The problem is that as soon as the Emitter enters the loop, the MainWindow app freezes. I believe the issue is with the python GIL, because, when I add a short timeout to the while loop time.sleep(0.3), the MainWindow become interactive.
Does anyone have a solution on how can I run Emitter without impacting or freezing the MainWindow app?