![](/img/trans.png)
[英]PyQt5 cannot update progress bar from thread and received the error “Cannot create children for a parent that is in a different thread”
[英]Error with python program with pyqt5 and sqlite, Cannot create children for a parent that is in a different thread
我使用 pyqt5 和 sqlite db 制作了一个程序。
它随机选择一个数据库的行文本并显示在文本浏览器小部件中,并在我每次按下按钮时复制到剪贴板。
并使用键盘模块,挂钩ctrl + v然后检查标签小部件以重复上一个按钮的功能。
但是当我按下ctrl + v 时,它在 Pycharm 中不起作用并显示此错误消息
Process finished with exit code -1073740791 (0xC0000409)
当我在终端中运行代码时,再次出现此错误消息
QObject: Cannot create children for a parent that is in a different thread.
(Parent is QTextDocument(0x207618a6770), parent's thread is QThread(0x2075f5acef0), current thread is QThread(0x20761d818d0)
我想可能是线程问题。 但我没有使用线程。 这是我的 pyqt5 小部件的 ui 图像和我的源代码。
我怎样才能使这段代码工作?
import sys
from PyQt5.QtWidgets import *
from PyQt5 import uic
import sqlite3
import random
import pyperclip
import keyboard
from time import sleep
form_class = uic.loadUiType("exam.ui")[0]
class WindowClass(QMainWindow, form_class) :
def __init__(self) :
super().__init__()
self.setupUi(self)
self.pb1.clicked.connect(self.bt1)
self.pb2.clicked.connect(self.bt2)
self.pb3.clicked.connect(self.bt3)
self.pb4.clicked.connect(self.bt4)
self.pb5.clicked.connect(self.bt5)
self.con = sqlite3.connect("exam.db")
self.cursor = self.con.cursor()
keyboard.add_hotkey("ctrl+v", self.kt)
def bt1(self):
self.lb1.clear()
self.tb.clear()
self.lb1.setText("a")
self.cursor.execute("SELECT max(rowid) FROM a")
maxrow = self.cursor.fetchone()
r = random.randrange(1, maxrow[0] + 1)
self.cursor.execute("SELECT * FROM a WHERE rowid =?", (r,))
t = self.cursor.fetchone()
self.tb.setPlainText(t[0])
pyperclip.copy(t[0] + "\n")
def bt2(self):
self.lb1.clear()
self.tb.clear()
self.lb1.setText("b")
self.cursor.execute("SELECT max(rowid) FROM b")
maxrow = self.cursor.fetchone()
r = random.randrange(1, maxrow[0] + 1)
self.cursor.execute("SELECT * FROM b WHERE rowid =?", (r,))
t = self.cursor.fetchone()
self.tb.setPlainText(t[0])
pyperclip.copy(t[0] + "\n")
def bt3(self):
self.lb1.clear()
self.tb.clear()
self.lb1.setText("c")
self.cursor.execute("SELECT max(rowid) FROM c")
maxrow = self.cursor.fetchone()
r = random.randrange(1, maxrow[0] + 1)
self.cursor.execute("SELECT * FROM c WHERE rowid =?", (r,))
t = self.cursor.fetchone()
self.tb.setPlainText(t[0])
pyperclip.copy(t[0] + "\n")
def bt4(self):
self.lb1.clear()
self.tb.clear()
self.lb1.setText("d")
self.cursor.execute("SELECT max(rowid) FROM d")
maxrow = self.cursor.fetchone()
r = random.randrange(1, maxrow[0] + 1)
self.cursor.execute("SELECT * FROM d WHERE rowid =?", (r,))
t = self.cursor.fetchone()
self.tb.setPlainText(t[0])
pyperclip.copy(t[0] + "\n")
def bt5(self):
self.lb1.clear()
self.tb.clear()
self.lb1.setText("e")
self.cursor.execute("SELECT max(rowid) FROM e")
maxrow = self.cursor.fetchone()
r = random.randrange(1, maxrow[0] + 1)
self.cursor.execute("SELECT * FROM e WHERE rowid =?", (r,))
t = self.cursor.fetchone()
self.tb.setPlainText(t[0])
pyperclip.copy(t[0] + "\n")
def kt(self):
if self.lb1.text() == "a":
self.bt1()
elif self.lb1.text == "b":
self.bt2()
elif self.lb1.text == "c":
self.bt3()
elif self.lb1.text == "d":
self.bt4()
elif self.lb1.text == "e":
self.bt5()
if __name__ == "__main__" :
app = QApplication(sys.argv)
myWindow = WindowClass()
myWindow.show()
app.exec_()
我只是添加了一个 db 和 ui 文件。
与使用 add_hotkey 注册的快捷方式关联的回调在辅助线程中执行,这意味着您正在从另一个线程修改 GUI,而 Qt 抛出该错误是禁止的。 解决方案是使用从辅助线程发出的信号来调用 kt 方法:
# ...
from PyQt5.QtCore import QObject, pyqtSignal
class KeyboardManager(QObject):
pasteSignal = pyqtSignal()
def start(self):
keyboard.add_hotkey("ctrl+v", self._ctrl_v_callback)
def _ctrl_v_callback(self):
self.pasteSignal.emit()
class WindowClass(QMainWindow, form_class):
def __init__(self):
super().__init__()
self.setupUi(self)
self.pb2.clicked.connect(self.bt2)
self.pb3.clicked.connect(self.bt3)
self.pb4.clicked.connect(self.bt4)
self.pb5.clicked.connect(self.bt5)
self.con = sqlite3.connect("exam.db")
self.cursor = self.con.cursor()
keyboard_manager = KeyboardManager(self) keyboard_manager.pasteSignal.connect(self.kt) keyboard_manager.start()
def bt1(self):
# ...
除了前面的错误,你还有一个小错误:如果要获取文本,必须使用带括号的 text() 方法,但是没有正确操作,解决方法如下:
def kt(self):
if self.lb1.text() == "a":
self.bt1()
elif self.lb1.text() == "b":
self.bt2()
elif self.lb1.text() == "c":
self.bt3()
elif self.lb1.text() == "d":
self.bt4()
elif self.lb1.text() == "e":
self.bt5()
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.