это ui_main из моего скрипта Python:
import ui_nova
from PySide6.QtCore import (QCoreApplication, Signal, QThread, QObject, QRunnable, Slot, QThreadPool)
from PySide6 import QtCore
from PySide6.QtGui import *
from PySide6 import QtWidgets
from PySide6.QtWidgets import (QApplication, QMainWindow, QWidget)
from threading import Thread
import conexoes
import threading
import sys
import traceback
class Sinais(QObject):
finished = Signal()
progress = Signal(int)
class Executora(QThread):
funcao = None
def __init__(self):
super(Executora, self).__init__()
self.sinais = Sinais()
self.funcaoaExecutar = None
self.finished = self.sinais.finished
self.progress = self.sinais.progress
def nomeDaFuncao(self, funcao):
self.funcaoaExecutar = funcao
@Slot()
def runner(self, funcao):
processo = conexoes.Conexoes()
aExecutar = funcao
execute = eval(f'processo.{aExecutar}')
try:
execute()
except:
traceback.print_exc()
exctype, value = sys.exc_info()[:2]
self.signals.error.emit((exctype, value, traceback.format_exc()))
else:
print("rodou")
finally:
self.finished.emit()
class UIMainConexao(QMainWindow, ui_nova.Ui_MainWindow):
def __init__(self):
super(UIMainConexao, self).__init__()
self.setupUi(self)
self.MainWW.setWindowFlags(ui_nova.QtCore.Qt.FramelessWindowHint)
self.MainWW.setAttribute(ui_nova.Qt.WA_TranslucentBackground)
self.buttonFechar.clicked.connect(self.close)
self.buttonMinimizar.clicked.connect(self.showMinimized)
self.threadpool = QThreadPool()
self.offset = None
print("Multithreading with maximum %d threads" % self.threadpool.maxThreadCount())
# install the event filter on the infoBar widget
self.frameToolBar.installEventFilter(self)
self.buttonHome.clicked.connect(lambda: self.stackedWidget.setCurrentWidget(self.pageInicial))
self.buttonUserConfig.clicked.connect(lambda: self.stackedWidget.setCurrentWidget(self.pageUser))
self.buttonEmpresas.clicked.connect(lambda: self.execute("boletoBancoX"))
def eventFilter(self, source, event):
if source == self.frameToolBar:
if event.type() == ui_nova.QtCore.QEvent.MouseButtonPress:
self.offset = event.pos()
elif event.type() == ui_nova.QtCore.QEvent.MouseMove and self.offset is not None:
# no need for complex computations: just use the offset to compute
# "delta" position, and add that to the current one
self.move(self.pos() - self.offset + event.pos())
# return True to tell Qt that the event has been accepted and
# should not be processed any further
return True
elif event.type() == ui_nova.QtCore.QEvent.MouseButtonRelease:
self.offset = None
# let Qt process any other event
return super().eventFilter(source, event)
@Slot()
def execute(self, funcao):
aExecutar = funcao
self.thread = QThread()
self.worker = Executora()
self.worker.moveToThread(self.thread)
self.thread.started.connect(lambda: print("Iniciou"))
self.thread.started.connect(lambda: self.worker.runner(aExecutar))
self.worker.finished.connect(lambda: print("É PRA FINALIZAR"))
self.worker.finished.connect(self.thread.quit)
self.worker.finished.connect(self.worker.deleteLater)
self.thread.finished.connect(self.thread.deleteLater)
self.thread.start()
Этот проект Python имеет длинную структуру с большим количеством py-файлов. Исполняемый файл будет содержать около 70-100 страниц с различными процессами, которые будут выполняться ОДИН ЗА РАЗ.
В «Conexoes» есть подключения ко всем файлам и процессам, которые будут выполняться, поэтому я создал метод для привязки каждой кнопки (я добавлю все подключения кнопок) к их соответствующему методу в conexoes, указав только имя, используя def execute .
Когда я запускаю процесс, он будет работать, и графический интерфейс зависает во время процесса, но если я использую потоки демона, скрипт выполнит первые шаги правильной функции (графический интерфейс не зависает), но произойдет сбой, потому что он не смог получить SAPEngineScript.
Я уже пробовал читать много сайтов, как использовать потоки в python и вставлять код, но все не работало должным образом. Я действительно не знаю, что я делаю.
Итак, после долгих поисков я нашел решение, которое, я думаю, может быть очень полезным для всех, кто использует QT с SAP. По сути, когда вы запускаете функцию sap с использованием потоков, вы получите сообщение об ошибке Object SAPGUI, поэтому решение для этого — просто импортировать pythoncom для вашего кода и вставить «pythoncom.CoInitialize ()» перед строкой getObject («SAPGUI» ). Теперь я использую Daemon Thread для выполнения функции без зависаний графического интерфейса.
Бывший:
import win32com.client
import pythoncom
def processoSAP(self):
try:
pythoncom.CoInitialize()
self.SapGuiAuto = win32com.client.GetObject("SAPGUI")
if not type(self.SapGuiAuto) == win32com.client.CDispatch:
return
self.application = self.SapGuiAuto.GetScriptingEngine
except NameError:
print(NameError)
Где нашел: https://django.fun/ru/qa/44126/
QThread.start()
автоматически вызывает методrun
, которого нет в вашем потоке. Создайте минимальный воспроизводимый пример.