SAP, Python и PySide6 — графический интерфейс зависает, когда я выполняю другой класс с длительным процессом

это 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 и вставлять код, но все не работало должным образом. Я действительно не знаю, что я делаю.

QThread.start() автоматически вызывает метод run, которого нет в вашем потоке. Создайте минимальный воспроизводимый пример.
Alexander 20.11.2022 10:20
14 Задание: Типы данных и структуры данных Python для DevOps
14 Задание: Типы данных и структуры данных Python для DevOps
проверить тип данных используемой переменной, мы можем просто написать: your_variable=100
Python PyPDF2 - запись метаданных PDF
Python PyPDF2 - запись метаданных PDF
Python скрипт, который будет записывать метаданные в PDF файл, для этого мы будем использовать PDF ридер из библиотеки PyPDF2 . PyPDF2 - это...
Переменные, типы данных и операторы в Python
Переменные, типы данных и операторы в Python
В Python переменные используются как место для хранения значений. Пример переменной формы:
Почему Python - идеальный выбор для проекта AI и ML
Почему Python - идеальный выбор для проекта AI и ML
Блог, которым поделился Harikrishna Kundariya в нашем сообществе Developer Nation Community.
Как автоматически добавлять котировки в заголовки запросов с помощью PyCharm
Как автоматически добавлять котировки в заголовки запросов с помощью PyCharm
Как автоматически добавлять котировки в заголовки запросов с помощью PyCharm
Анализ продукта магазина на Tokopedia
Анализ продукта магазина на Tokopedia
Tokopedia - это место, где продавцы могут продавать свои товары. Товар должен быть размещен на витрине, чтобы покупателям было легче найти товар...
0
1
52
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Итак, после долгих поисков я нашел решение, которое, я думаю, может быть очень полезным для всех, кто использует 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/

Другие вопросы по теме