PySide: problem with starting QThread with a signal when using debugger

已回答

Hello,

There are two main approaches for using QThread in Qt: 1) use worker object that is not derived from QThread and connect signals from QThread to the worker and 2) derive from QThread and override 'run' method. I'm using first approach.

The code below works as expected when I start it with normal 'run' button (without debugger). BUT if I start it with debugger it looks like 'BackgroundWorker.process' function is called from main thread, not from additional thread.


from PySide.QtCore import QThread, QObject, QCoreApplication, QTimer, Signal, Qt, Slot
import time
import sys

class BackgroundWorker(QObject):

finished = Signal()

def __init__(self):
QObject.__init__(self)

def start(self):
self.th = QThread()
self.th.setObjectName("bkg_thread")

self.th.started.connect(self.process) # bug: process called from main thread
# self.th.started.connect(self.process, type=Qt.DirectConnection) # works ok

self.th.finished.connect(app.quit)
self.finished.connect(self.th.quit)

self.moveToThread(self.th)
self.th.start()

def process(self):
print ('Background process: thread name: {}'.format(QThread.currentThread().objectName()))

for i in range(0, 3):
print ('Background thread', i)
time.sleep(1)

self.finished.emit()

def main_thread_func():
time.sleep(0.1)
print ('Main thread func: thread name: {}'.format(QThread.currentThread().objectName()))
for i in range(0, 3):
print ('In main thread', i)
time.sleep(1)

if __name__ == '__main__':
app = QCoreApplication(sys.argv)
bw = BackgroundWorker()
QThread.currentThread().setObjectName("main_thread")

QTimer.singleShot(1, bw.start)
QTimer.singleShot(200, main_thread_func)
app.exec_()

Output without debugger:

Background process: thread name: bkg_thread
('Background thread', 0)
Main thread func: thread name: main_thread
('In main thread', 0)
('Background thread', 1)
('In main thread', 1)
('Background thread', 2)
('In main thread', 2)

Output WITH debugger:

C:\Dev\Python27\python.exe "C:\Program Files\JetBrains\PyCharm Community Edition 2018.2.1\helpers\pydev\pydevd.py" --multiproc --qt-support=pyside --client 127.0.0.1 --port 52139 --file C:/Users/Roman/PycharmProjects/untitled1/test.py
pydev debugger: process 24820 is connecting

Connected to pydev debugger (build 182.3911.33)
Background process: thread name: main_thread
('Background thread', 0)
('Background thread', 1)
('Background thread', 2)
Main thread func: thread name: main_thread
('In main thread', 0)
('In main thread', 1)
('In main thread', 2)

Process finished with exit code 0

Note that current thread in 'process' function has name 'main_thread' when running under debugger.

In a real application this result in inability to run application under debugger, because main GUI becomes unresponsive.

At the same time, if I connect 'QThread.started' signal to 'BackgroundWorker.process' function explicitly specifying 'direct connection' (see commented line in the code) then everything works ok - both threads run simultaneously under debugger.

Is this a known issue? How can this be explained? Could you recommend any workaround (better than connecting using direct connection)?

I guess this is somehow related to pydev_monkey_qt.py. I tried to debug what is happening there but didn't succeed.

PyCharm 2018.2.1 (Community Edition)
Build #PC-182.3911.33, built on August 5, 2018
JRE: 1.8.0_152-release-1248-b8 amd64
JVM: OpenJDK 64-Bit Server VM by JetBrains s.r.o
Windows 10 10.0

Python is 2.7.15, PySide 1.2.4

 

P.S. I checked with PySide2 (5.11.1) and python 3.7 and everything works ok there. But monkey-patching isn't applied to PySide2, I guess.

 

 

3
Avatar
Permanently deleted user

Same story here. Works without the debugger, breaks when it is attached. 

0

Same issue here. Voted.

0

请先登录再写评论。