PyQt5启动报错:qt.qpa.plugin与QObject线程问题求助
解决PyQt5+OpenCV+MySQL整合代码的三类问题
问题列表与解决方案
1. sipPyTypeDict()弃用警告
原因:PyQt5与sip库版本不兼容,旧版sip的API已被弃用。
解决方法:
- 升级sip到兼容版本:
pip install --upgrade sip - 若升级后仍存在警告,同步更新PyQt5:
pip install --upgrade PyQt5
2. QObject::moveToThread线程迁移错误
原因:OpenCV的Qt模块与PyQt5的线程上下文冲突,OpenCV初始化时创建的Qt对象无法迁移到PyQt主线程。
解决方法:
将cv2的导入时机延后到QApplication创建之后,避免线程初始化冲突:
if __name__ == '__main__': app = QApplication(sys.argv) import cv2 # 移至此处导入 administrator = Administrator() main = Main() add_admin = AddAdmin() administrator.show() app.exec()
或者强制指定OpenCV使用非Qt后端:
import os os.environ["OPENCV_UI_BACKEND"] = "GTK" # 或设置为"none"禁用UI后端 import cv2
3. qt.qpa.plugin无法加载xcb插件(已找到但无法初始化)
原因:OpenCV自带的Qt插件与系统PyQt5的Qt库版本不匹配,或缺少xcb相关依赖。
解决方法:
- 指定PyQt5使用系统Qt插件:
在代码开头添加环境变量,让PyQt优先调用系统自带的Qt插件,而非OpenCV自带的:import os # Ubuntu系统示例路径,其他发行版需调整 os.environ["QT_PLUGIN_PATH"] = "/usr/lib/x86_64-linux-gnu/qt5/plugins" import cv2 - 安装完整的xcb依赖库:
sudo apt-get install libxcb-cursor0 libxcb-keysyms1 libxcb-randr0 libxcb-render-util0 libxcb-shape0 libxcb-xkb1 libxkbcommon-x11-0 - 降级OpenCV版本:
若新版本OpenCV与PyQt5兼容性差,尝试安装稳定旧版:pip install opencv-python==4.5.5.62
用户代码
import re import sys import webbrowser import mysql.connector from PyQt5.QtWidgets import QApplication, QDialog, QButtonGroup, QTableWidgetItem from PyQt5.uic import loadUi import cv2 try: db = mysql.connector.connect(host="localhost", user="root", password="", database="memoire") my_cursor = db.cursor() bd_connection = True except mysql.connector.errors.DatabaseError: bd_connection = False def administrator_window(): administrator.show() add_admin.close() def add_admin_window(): add_admin.show() def main_window(): main.show() administrator.close() class Administrator(QDialog): def __init__(self): super(Administrator, self).__init__() loadUi("ui/admin/administrator.ui", self) self.hide_icon() self.event_handler() self.pushButton_eye.clicked.connect(self.change_password_mode) self.button_validate.clicked.connect(self.check_connection) def event_handler(self): self.button_facebook.clicked.connect( lambda: webbrowser.open("https://web.facebook.com/UNHorizons/?_rdc=1&_rdr")) self.button_facebook.enterEvent = lambda event: self.label_facebook.show() self.button_facebook.leaveEvent = lambda event: self.label_facebook.hide() self.button_instagram.clicked.connect(lambda: webbrowser.open("https://www.instagram.com/unhorizons/")) self.button_instagram.enterEvent = lambda event: self.label_instagram.show() self.button_instagram.leaveEvent = lambda event: self.label_instagram.hide() self.button_youtube.clicked.connect( lambda: webbrowser.open("https://www.youtube.com/channel/UC7Y3KQIh7S6Y3vI41rsu9vQ")) self.button_youtube.enterEvent = lambda event: self.label_youtube.show() self.button_youtube.leaveEvent = lambda event: self.label_youtube.hide() def hide_icon(self): self.label_facebook.hide() self.label_instagram.hide() self.label_youtube.hide() def change_password_mode(self): current_echo_mode = self.lineEdit_pass.echoMode() if current_echo_mode == self.lineEdit_pass.Normal: self.lineEdit_pass.setEchoMode(self.lineEdit_pass.Password) elif current_echo_mode == self.lineEdit_pass.Password: self.lineEdit_pass.setEchoMode(self.lineEdit_pass.Normal) def check_connection(self): if bd_connection: identifier = self.lineEdit_email.text() password = self.lineEdit_pass.text() id_exists = False try: my_cursor.execute("SELECT * FROM administrator") result = my_cursor.fetchall() if not result: print("empty") self.label_error.clear() add_admin_window() else: for row in result: if (identifier == row[3] or identifier == row[4]) and password == row[5]: self.label_error.clear() id_exists = True Administrator.identifier = row[4] main_window() if not id_exists: self.label_error.setText("Incorrect email address or password") except mysql.connector.errors.OperationalError: self.label_error.setText("Query expired, please try again later") else: self.label_error.setText("Connection impossible") class Main(QDialog): def __init__(self): super(Main, self).__init__() loadUi("ui/admin/main_admin.ui", self) self.tableWidget.hide() self.pushButton_watch.clicked.connect(self.show_student) self.pushButton_scanner.clicked.connect(self.show_student) def show_student(self): self.tableWidget.show() try: my_cursor.execute("SELECT * FROM registration") result = my_cursor.fetchall() headers = [column_description[0] for column_description in my_cursor.description[1:]] self.tableWidget.setColumnCount(len(headers)) self.tableWidget.setRowCount(len(result)) self.tableWidget.setHorizontalHeaderLabels(headers) for row_index, row_data in enumerate(result): for column_index, cell_value in enumerate(row_data[1:]): if column_index == 10 and cell_value is not None: cell_value = "Existing QR code" elif column_index == 11 and cell_value is not None: cell_value = "Existing Profile" item = QTableWidgetItem(str(cell_value)) self.tableWidget.setItem(row_index, column_index, item) self.tableWidget.resizeColumnsToContents() except mysql.connector.errors.OperationalError: self.label_error.setText("Query expired, please try again later") def scanner(self): try: print('3') except mysql.connector.errors.OperationalError: self.label_error.setText("Query expired, please try again later") class AddAdmin(QDialog): def __init__(self): super(AddAdmin, self).__init__() loadUi("ui/admin/add_admin.ui", self) self.button_group = QButtonGroup() self.button_group.addButton(self.radio_male) self.button_group.addButton(self.radio_female) self.pushButton_validate.clicked.connect(self.check_registration) self.pushButton_cancel.clicked.connect(administrator_window) def check_registration(self): selected_radio = self.button_group.checkedButton() name = self.lineEdit_name.text() username = self.lineEdit_username.text() email = self.lineEdit_email.text() password = self.lineEdit_pass.text() confirm_password = self.lineEdit_pass_2.text() if selected_radio is not None: gender = selected_radio.text() if name and name.replace(' ', '').replace('-', '').isalpha(): if username and username.replace('_', '').isalnum(): if re.match(r"[^@]+@[^@]+\.[^@]+", email): if len(password) >= 5: if password == confirm_password: my_cursor.execute("SELECT * FROM administrator WHERE username = %s", (username,)) result = my_cursor.fetchone() if result: self.label_error.setText("Username already in use") else: my_cursor.execute("SELECT * FROM administrator WHERE email = %s", (email,)) result = my_cursor.fetchone() if result: self.label_error.setText("Email already in use") else: my_cursor.execute("INSERT INTO `administrator`(`full_name`, `gender`, `username`, `email`, `password`) VALUES (%s, %s, %s, %s, %s)", (name, gender, username, email, password)) db.commit() add_admin.close() else: self.label_error.setText("Incompatible passwords") else: self.label_error.setText("Password must be at least 5 characters long") else: self.label_error.setText("Invalid email address") else: self.label_error.setText("Username must be alphanumeric") else: self.label_error.setText("Invalid name") else: self.label_error.setText("Please select a gender") if __name__ == '__main__': app = QApplication(sys.argv) administrator = Administrator() main = Main() add_admin = AddAdmin() administrator.show() app.exec()
完整报错信息
/home/allan/Desktop/python/memoire/memoire_refactor/administrateur.py:32: DeprecationWarning: sipPyTypeDict() is deprecated, the extension module should use sipPyTypeDictRef() instead class Administrator(QDialog): /home/allan/Desktop/python/memoire/memoire_refactor/administrateur.py:99: DeprecationWarning: sipPyTypeDict() is deprecated, the extension module should use sipPyTypeDictRef() instead class Main(QDialog): /home/allan/Desktop/python/memoire/memoire_refactor/administrateur.py:141: DeprecationWarning: sipPyTypeDict() is deprecated, the extension module should use sipPyTypeDictRef() instead class AddAdmin(QDialog): QObject::moveToThread: Current thread (0x55b67018b2d0) is not the object's thread (0x55b6708608e0). Cannot move to target thread (0x55b67018b2d0) qt.qpa.plugin: Could not load the Qt platform plugin "xcb" in "/home/allan/.local/lib/python3.10/site-packages/cv2/qt/plugins" even though it was found. This application failed to start because no Qt platform plugin could be initialized. Reinstalling the application may fix this problem. Available platform plugins are: xcb, eglfs, linuxfb, minimal, minimalegl, offscreen, vnc, wayland-egl, wayland, wayland-xcomposite-egl, wayland-xcomposite-glx, webgl.
内容的提问来源于stack exchange,提问作者Allan
相关产品推荐
相关产品推荐

