为什么线程在 PyQt5 中不起作用?
Why threading does not work in PyQt5?
部分代码如下:
...
self.startButton.clicked.connect(self.conc_thread)
def conc(self):
self.textField.clear()
word=self.searchBox.text()
path=r'D:\python1\wxPython\NYConc\Fiction'
for filename in glob.glob(os.path.join(path, '*.txt')):
try:
file=open(filename, 'r')
read=file.read()
file.close()
pattern=re.findall(r'.{40} '+word+r' .{40}', read)
for i in pattern:
self.textField.append(i)
except:
continue
def conc_thread(self):
tg=threading.Thread(target=self.conc)
tg.start()
它给我这个错误信息:
“QObject:无法为不同线程中的父对象创建子对象。
(父线程是QTextDocument(0xd08b98),父线程是QThread(0xc6f620),当前线程是QThread(0x4a2c810)"
请问我该如何解决?
鉴于您的 self.textField
是一个 QTextEdit
,每当您调用其 append
方法时,都会创建一个 QTextCursor
作为 QTextEdit
的子项底层 QTextDocument
对象。
这有什么问题吗? Qt 不允许任何 QObject-derived class 在与父线程不同的线程中拥有子线程 'living'。
如何解决?由于您已经在使用它们,所以让我们使用信号和槽。
首先像这样定义一个信号:
appendText = pyqtSignal(str)
和对应的插槽:
def appendToTextField(self, text):
self.textField.append(text)
连接他们:
self.appendText.connect(self.appendToTextField)
然后代替:
for i in pattern:
self.textField.append(i)
做:
for i in pattern:
self.appendText.emit(i)
appendToTextField
插槽应该 运行 在正确的线程中,QTextEdit
底层 QTextDocument
所在的线程,因此 Qt 将允许添加新的子项
部分代码如下:
...
self.startButton.clicked.connect(self.conc_thread)
def conc(self):
self.textField.clear()
word=self.searchBox.text()
path=r'D:\python1\wxPython\NYConc\Fiction'
for filename in glob.glob(os.path.join(path, '*.txt')):
try:
file=open(filename, 'r')
read=file.read()
file.close()
pattern=re.findall(r'.{40} '+word+r' .{40}', read)
for i in pattern:
self.textField.append(i)
except:
continue
def conc_thread(self):
tg=threading.Thread(target=self.conc)
tg.start()
它给我这个错误信息: “QObject:无法为不同线程中的父对象创建子对象。 (父线程是QTextDocument(0xd08b98),父线程是QThread(0xc6f620),当前线程是QThread(0x4a2c810)"
请问我该如何解决?
鉴于您的 self.textField
是一个 QTextEdit
,每当您调用其 append
方法时,都会创建一个 QTextCursor
作为 QTextEdit
的子项底层 QTextDocument
对象。
这有什么问题吗? Qt 不允许任何 QObject-derived class 在与父线程不同的线程中拥有子线程 'living'。
如何解决?由于您已经在使用它们,所以让我们使用信号和槽。
首先像这样定义一个信号:
appendText = pyqtSignal(str)
和对应的插槽:
def appendToTextField(self, text):
self.textField.append(text)
连接他们:
self.appendText.connect(self.appendToTextField)
然后代替:
for i in pattern:
self.textField.append(i)
做:
for i in pattern:
self.appendText.emit(i)
appendToTextField
插槽应该 运行 在正确的线程中,QTextEdit
底层 QTextDocument
所在的线程,因此 Qt 将允许添加新的子项