Я пытался создать небольшую программу на Python с графическим интерфейсом, используя Pyside6. Я столкнулся с проблемой при создании потока для выполнения задачи воркером (проверка файлов с определенным условием и последующее копирование их в другую папку).
Проблема в следующем: я хочу обрабатывать ошибки, исходящие от воркера, чтобы появлялось всплывающее окно для выхода из приложения. Однако, когда ошибка обнаружена и выдан сигнал, появляется всплывающее окно, но приложение полностью зависает, и мне приходится закрыть его вручную.
Вот соответствующий код (используется DualOutput, поэтому я могу видеть отпечатки в графическом интерфейсе; проблема сохраняется даже без него):
from PySide6.QtCore import *
from PySide6.QtGui import *
from PySide6.QtWidgets import *
from pathlib import Path
import sys
import transfer
import datetime
import os
import atexit
import traceback
class Ui_MainWindow(object):
@Slot()
def cancel(self,worker):
worker.stop()
def start_search_and_Copy(self):
self.plainTextEdit.clear()
# check if overwrite files or not
if self.checkBox.isChecked():
self.overwrite = True
else :
self.overwrite = False
# Thread + Worker
self.thread = QThread()
self.workers1 = Worker1(self.lineEdit.text(), self.lineEdit_3.text(), self.dateEdit.date(), self.overwrite)
self.workers1.moveToThread(self.thread)
self.workers1.finished.connect(lambda: self.setAllEnabled(True))
# Connect signals
self.thread.started.connect(self.workers1.run)
self.workers1.errorOccurred.connect(self.worker_error,type=Qt.QueuedConnection)
#self.workers1.finished.connect(self.test)
self.workers1.finished.connect(lambda: self.setAllEnabled(True))
self.workers1.finished.connect(self.thread.quit)
self.workers1.finished.connect(self.workers1.deleteLater)
self.thread.finished.connect(self.thread.deleteLater)
# Start thread
self.thread.start()
def worker_error(self, msg):
log_caught_exception(msg)
messageBox = QMessageBox()
messageBox.setWindowTitle("Error")
messageBox.setText("An error occurred:")
messageBox.setInformativeText(str(msg))
messageBox.setIcon(QMessageBox.Critical)
messageBox.setStandardButtons(QMessageBox.Ok)
messageBox.setWindowModality(Qt.ApplicationModal)
messageBox.exec()
messageBox.raise_()
messageBox.activateWindow()
QApplication.processEvents()
messageBox.buttonClicked.connect(lambda _: QApplication.instance().quit())
def setupUi(self, MainWindow):
if not MainWindow.objectName():
MainWindow.setObjectName(u"MainWindow")
MainWindow.resize(900, 7223)
self.actionSearch_Folder = QAction(MainWindow)
self.actionSearch_Folder.setObjectName(u"actionSearch_Folder")
self.actionSearch_Folder.setCheckable(False)
icon = QIcon(QIcon.fromTheme(u"folder"))
self.actionSearch_Folder.setIcon(icon)
self.centralwidget = QWidget(MainWindow)
self.centralwidget.setObjectName(u"centralwidget")
self.centralwidget.setMinimumSize(QSize(800, 549))
self.gridLayout = QGridLayout(self.centralwidget)
self.gridLayout.setObjectName(u"gridLayout")
self.frame = QFrame(self.centralwidget)
self.frame.setObjectName(u"frame")
self.pushButton = QPushButton(self.frame)
self.pushButton.setObjectName(u"pushButton")
self.pushButton.setGeometry(QRect(9, 63, 91, 24))
self.pushButton.clicked.connect(self.start_search_and_Copy)
self.pushButton.clicked.connect(lambda: self.setAllEnabled(False))
(...)
self.plainTextEdit = QPlainTextEdit(self.frame)
self.plainTextEdit.setObjectName(u"plainTextEdit")
self.plainTextEdit.setGeometry(QRect(10, 530, 861, 131))
self.plainTextEdit.setReadOnly(True)
dual_output = DualOutput(self.plainTextEdit)
sys.stdout = dual_output
sys.stderr = dual_output
sys.excepthook = log_uncaught_exceptions
(...)
self.lineEdit = QLineEdit(self.frame)
self.lineEdit.setObjectName(u"lineEdit")
self.lineEdit.setGeometry(QRect(48, 9, 311, 21))
self.lineEdit.textEdited.connect(self.path_change)
(...)
self.retranslateUi(MainWindow)
QMetaObject.connectSlotsByName(MainWindow)
# setupUi
def retranslateUi(self, MainWindow):
(...)
# retranslateUi
class SearchMixin:
def search_files(self,date_lim, path):
filtered_files = []
(...)
return filtered_files
class Worker1(QObject, SearchMixin):
errorOccurred = Signal(object)
finished = Signal()
files = None
plainTextEdit = None
path = None
date_lim = None
destination = None
def __init__(self, path, destination, date_lim,overwrite):
super().__init__()
self.path = path
self.destination = destination
self.date_lim = date_lim
self._running = True
self.overwrite = overwrite
def run(self) -> None:
try:
(...)
filtered_files = self.search_files(self.date_lim, self.path)
if self._running:
if filtered_files:
self.files = filtered_files
total = len(self.files)
(...)
else :
print("No files")
i = 0
total=len(filtered_files)
for file in self.files: #
Подробнее здесь: https://stackoverflow.com/questions/798 ... curs-compl
Открытие всплывающего окна при возникновении ошибки работника, работающего в Qthread, полностью зависает программа ⇐ Python
Программы на Python
1762984701
Anonymous
Я пытался создать небольшую программу на Python с графическим интерфейсом, используя Pyside6. Я столкнулся с проблемой при создании потока для выполнения задачи воркером (проверка файлов с определенным условием и последующее копирование их в другую папку).
Проблема в следующем: я хочу обрабатывать ошибки, исходящие от воркера, чтобы появлялось всплывающее окно для выхода из приложения. Однако, когда ошибка обнаружена и выдан сигнал, появляется всплывающее окно, но приложение полностью зависает, и мне приходится закрыть его вручную.
Вот соответствующий код (используется DualOutput, поэтому я могу видеть отпечатки в графическом интерфейсе; проблема сохраняется даже без него):
from PySide6.QtCore import *
from PySide6.QtGui import *
from PySide6.QtWidgets import *
from pathlib import Path
import sys
import transfer
import datetime
import os
import atexit
import traceback
class Ui_MainWindow(object):
@Slot()
def cancel(self,worker):
worker.stop()
def start_search_and_Copy(self):
self.plainTextEdit.clear()
# check if overwrite files or not
if self.checkBox.isChecked():
self.overwrite = True
else :
self.overwrite = False
# Thread + Worker
self.thread = QThread()
self.workers1 = Worker1(self.lineEdit.text(), self.lineEdit_3.text(), self.dateEdit.date(), self.overwrite)
self.workers1.moveToThread(self.thread)
self.workers1.finished.connect(lambda: self.setAllEnabled(True))
# Connect signals
self.thread.started.connect(self.workers1.run)
self.workers1.errorOccurred.connect(self.worker_error,type=Qt.QueuedConnection)
#self.workers1.finished.connect(self.test)
self.workers1.finished.connect(lambda: self.setAllEnabled(True))
self.workers1.finished.connect(self.thread.quit)
self.workers1.finished.connect(self.workers1.deleteLater)
self.thread.finished.connect(self.thread.deleteLater)
# Start thread
self.thread.start()
def worker_error(self, msg):
log_caught_exception(msg)
messageBox = QMessageBox()
messageBox.setWindowTitle("Error")
messageBox.setText("An error occurred:")
messageBox.setInformativeText(str(msg))
messageBox.setIcon(QMessageBox.Critical)
messageBox.setStandardButtons(QMessageBox.Ok)
messageBox.setWindowModality(Qt.ApplicationModal)
messageBox.exec()
messageBox.raise_()
messageBox.activateWindow()
QApplication.processEvents()
messageBox.buttonClicked.connect(lambda _: QApplication.instance().quit())
def setupUi(self, MainWindow):
if not MainWindow.objectName():
MainWindow.setObjectName(u"MainWindow")
MainWindow.resize(900, 7223)
self.actionSearch_Folder = QAction(MainWindow)
self.actionSearch_Folder.setObjectName(u"actionSearch_Folder")
self.actionSearch_Folder.setCheckable(False)
icon = QIcon(QIcon.fromTheme(u"folder"))
self.actionSearch_Folder.setIcon(icon)
self.centralwidget = QWidget(MainWindow)
self.centralwidget.setObjectName(u"centralwidget")
self.centralwidget.setMinimumSize(QSize(800, 549))
self.gridLayout = QGridLayout(self.centralwidget)
self.gridLayout.setObjectName(u"gridLayout")
self.frame = QFrame(self.centralwidget)
self.frame.setObjectName(u"frame")
self.pushButton = QPushButton(self.frame)
self.pushButton.setObjectName(u"pushButton")
self.pushButton.setGeometry(QRect(9, 63, 91, 24))
self.pushButton.clicked.connect(self.start_search_and_Copy)
self.pushButton.clicked.connect(lambda: self.setAllEnabled(False))
(...)
self.plainTextEdit = QPlainTextEdit(self.frame)
self.plainTextEdit.setObjectName(u"plainTextEdit")
self.plainTextEdit.setGeometry(QRect(10, 530, 861, 131))
self.plainTextEdit.setReadOnly(True)
dual_output = DualOutput(self.plainTextEdit)
sys.stdout = dual_output
sys.stderr = dual_output
sys.excepthook = log_uncaught_exceptions
(...)
self.lineEdit = QLineEdit(self.frame)
self.lineEdit.setObjectName(u"lineEdit")
self.lineEdit.setGeometry(QRect(48, 9, 311, 21))
self.lineEdit.textEdited.connect(self.path_change)
(...)
self.retranslateUi(MainWindow)
QMetaObject.connectSlotsByName(MainWindow)
# setupUi
def retranslateUi(self, MainWindow):
(...)
# retranslateUi
class SearchMixin:
def search_files(self,date_lim, path):
filtered_files = []
(...)
return filtered_files
class Worker1(QObject, SearchMixin):
errorOccurred = Signal(object)
finished = Signal()
files = None
plainTextEdit = None
path = None
date_lim = None
destination = None
def __init__(self, path, destination, date_lim,overwrite):
super().__init__()
self.path = path
self.destination = destination
self.date_lim = date_lim
self._running = True
self.overwrite = overwrite
def run(self) -> None:
try:
(...)
filtered_files = self.search_files(self.date_lim, self.path)
if self._running:
if filtered_files:
self.files = filtered_files
total = len(self.files)
(...)
else :
print("No files")
i = 0
total=len(filtered_files)
for file in self.files: #
Подробнее здесь: [url]https://stackoverflow.com/questions/79818084/opening-a-pop-up-window-when-error-from-a-worker-running-in-qthread-occurs-compl[/url]
Ответить
1 сообщение
• Страница 1 из 1
Перейти
- Кемерово-IT
- ↳ Javascript
- ↳ C#
- ↳ JAVA
- ↳ Elasticsearch aggregation
- ↳ Python
- ↳ Php
- ↳ Android
- ↳ Html
- ↳ Jquery
- ↳ C++
- ↳ IOS
- ↳ CSS
- ↳ Excel
- ↳ Linux
- ↳ Apache
- ↳ MySql
- Детский мир
- Для души
- ↳ Музыкальные инструменты даром
- ↳ Печатная продукция даром
- Внешняя красота и здоровье
- ↳ Одежда и обувь для взрослых даром
- ↳ Товары для здоровья
- ↳ Физкультура и спорт
- Техника - даром!
- ↳ Автомобилистам
- ↳ Компьютерная техника
- ↳ Плиты: газовые и электрические
- ↳ Холодильники
- ↳ Стиральные машины
- ↳ Телевизоры
- ↳ Телефоны, смартфоны, плашеты
- ↳ Швейные машинки
- ↳ Прочая электроника и техника
- ↳ Фототехника
- Ремонт и интерьер
- ↳ Стройматериалы, инструмент
- ↳ Мебель и предметы интерьера даром
- ↳ Cантехника
- Другие темы
- ↳ Разное даром
- ↳ Давай меняться!
- ↳ Отдам\возьму за копеечку
- ↳ Работа и подработка в Кемерове
- ↳ Давай с тобой поговорим...
Мобильная версия