繁体   English   中英

SAP、Python 和 PySide6 - 当我执行另一个 class 时,GUI 冻结,过程很长

[英]SAP, Python and PySide6 - GUI freezes when i execute another class with a long long process

这是我的 python 脚本中的 ui_main:

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文件。 该 exe 将包含大约 70-100 个页面,其中包含将一次执行一个的不同进程。

在“Conexoes”中,连接到将要执行的所有文件和进程,因此我创建了一个方法来将每个按钮(我将添加所有按钮连接)链接到它们在 conexoes 中各自的方法,使用 def execute 给出名称.

当我开始这个过程时,将工作并且 GUI 在此过程中冻结,但如果我使用守护线程,脚本将运行正确的 function 的第一步(gui 不冻结),但会崩溃,因为他无法获得 SAPEngineScript。

我已经尝试阅读许多网站如何在 python 中使用线程并输入代码,但都无法正常工作。 我真的不知道我在做什么。

所以,经过更多的搜索,我找到了解决方案,我认为这对每个使用 QT 和 SAP 的人都非常有用。 基本上,当您使用线程启动 sap function 时,您将收到有关 Object SAPGUI 的错误,因此解决方案只是为您的代码导入 pythoncom 并在 getObject("SAPGUI" 行之前插入"pythoncom.CoInitialize()" ). 现在我正在使用 Daemon Thread 来执行 function 而不会冻结 de GUI。

前任:

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/en/qa/44126/

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM