带有pyqt5和sqlite的python程序出错,无法为处于不同线程中的父级创建子级

问题描述 投票:0回答:1

我使用pyqt5和sqlite db编写程序。

它是随机选择数据库的行文本,并在textbrowser小部件中显示,并在每次按下按钮时复制到剪贴板。

并使用键盘模块,钩住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 file linkui file link

我只是添加一个数据库和ui文件。

python pyqt5 qthread
1个回答
0
投票

与通过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()
© www.soinside.com 2019 - 2024. All rights reserved.