Как я могу обновлять текст в режиме реального времени при выполнении вычислений в QTextEdit без зависания интерфейса? - PullRequest
0 голосов
/ 16 июня 2020

У меня проблема с обновлением в реальном времени в QTextedit, потому что, когда я выполняю, экран остается неизменным c в течение нескольких секунд, пока он выполняет вычисления, но мне нужно, чтобы в QTextedit статус сообщения отображаются во время моделирования. Я пробовал использовать потоки, но я не очень хорошо это понимаю, так как это не сработает. Если бы кто-то мог мне помочь с этим, я был бы признателен, так как я не очень много занимаюсь проблемой Thread в Pyqt5. (Не понял) Большое спасибо

Прикрепляю код интерфейса:

TempClean.py

# -*- coding:utf-8 -*-

import os
import sys
import shutil
import getpass
import Optimization
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
import time

tmp = ""
deleteFileCount = 0
deleteFolderCount = 0

class TempRemove(QMainWindow, Optimization.Ui_OptimalWindow):
    def __init__(self, parent = None):
        super(QMainWindow, self).__init__(parent)
        self.initUI(self)
        self.Clean()

    def Task(self, folderName):
        global tmp, deleteFileCount, deleteFolderCount
        for the_file in os.listdir(folderName):
            file_path = os.path.join(folderName, the_file)
            indexNo = file_path.find('\\')
            itemName = file_path[indexNo + 1:]
            try:
                self.show()
                self.ScanInfo.repaint()
                if os.path.isfile(file_path):
                    os.unlink(file_path)
                    self.ScanInfo.append(str(tmp + ('%s file deleted' % itemName)))
                    deleteFileCount = deleteFileCount + 1


                elif os.path.isdir(file_path):
                    if file_path.__contains__('chocolatey'):
                        continue
                    shutil.rmtree(file_path)
                    self.ScanInfo.append(str(tmp + ('%s folder deleted' % itemName)))
                    deleteFolderCount = deleteFolderCount + 1

            except Exception as e:
                self.ScanInfo.append(str(tmp + ('Access Denied: %s' % itemName)))
            # self.ScanInfo.append(str(tmp))

    def Clean(self):
        self.show()
        self.ScanInfo.setText("")

        folder = 'C:/Users/' + getpass.getuser() + '\AppData\Local\Temp'
        self.Task(folder)

        # Chrome
        folder = 'C:/Users/' + getpass.getuser() + '\AppData\Local\Google\Chrome\User Data\Default\Cache'
        self.Task(folder)

        # Internet Explorer
        folder = 'C:/Users/' + getpass.getuser() + '\AppData\Local\Microsoft\Windows\INetCache'
        self.Task(folder)

        # Edge
        folder = 'C:/Users/' + getpass.getuser() + '\AppData\Local\Packages\Microsoft.MicrosoftEdge_8wekyb3d8bbwe\AC\Temp'
        self.Task(folder)


        global deleteFileCount, deleteFolderCount
        result = (str(deleteFileCount) + ' files and ' + str(deleteFolderCount) + ' folders deleted.') + '\n'
        self.ScanInfo.append(str(result))


if __name__ == '__main__':
    a = QApplication(sys.argv)
    app = TempRemove()
    app.show()
    a.exec_()

Optimization.py

# -*- coding: utf-8 -*-

import sys

from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *

class Ui_OptimalWindow(object):
    def initUI(self, OptimalWindow):
        OptimalWindow.setObjectName("OptimalWindow")
        OptimalWindow.setWindowTitle('Optimization')
        OptimalWindow.setWindowIcon(QIcon(".\image\Icon.jpg"))
        OptimalWindow.resize(600, 579) 
        OptimalWindow.center()  

        self.title = QLabel(OptimalWindow)
        self.title.setGeometry(QRect(0, 0, 600, 78))
        self.title.setText("")
        self.title.setPixmap(QPixmap(".\OptimalImage\\Optimization.jpg"))

        self.Main = QLabel(OptimalWindow)
        self.Main.setGeometry(QRect(0, 79, 600, 500))
        self.Main.setText("")
        self.Main.setPixmap(QPixmap(".\OptimalImage\\Main.png"))

        self.ScanInfo = QTextEdit(OptimalWindow)
        self.ScanInfo.setGeometry(QRect(40, 109, 500, 400))

    def center(self):
        qr = self.frameGeometry() 
        cp = QDesktopWidget().availableGeometry().center()
        qr.moveCenter(cp)

        self.move(qr.topLeft())

if __name__ == "__main__":
    import sys
    app = QApplication(sys.argv)
    OptimalWindow = QWidget()
    ui = Ui_OptimalWindow()
    ui.initUI(OptimalWindow)
    OptimalWindow.show()
    app.exec_()

1 Ответ

1 голос
/ 16 июня 2020

Длительные задачи замораживают GUI, поэтому их нужно запускать в другом потоке, и если вы хотите обновить GUI из вторичного потока, его следует отправить через сигналы:

# -*- coding:utf-8 -*-

import os
import sys
import shutil
import getpass
import Optimization

import threading

from PyQt5.QtCore import pyqtSignal, QObject
from PyQt5.QtWidgets import QApplication, QMainWindow


class CleanWorker(QObject):
    started = pyqtSignal()
    finished = pyqtSignal()
    logSignal = pyqtSignal(str)

    def __init__(self, parent=None):
        super().__init__(parent)

        self.delete_file_count = 0
        self.delete_folder_count = 0

    def clean(self):
        threading.Thread(target=self._execute, daemon=True).start()

    def _execute(self):
        self.delete_file_count = 0
        self.delete_folder_count = 0
        self.started.emit()

        folders = (
            os.path.join("C:/Users", getpass.getuser(), "AppData/Local/Temp"),
            os.path.join(
                "C:/Users/",  # Chrome
                getpass.getuser(),
                r"AppData/Local/Google/Chrome/User Data/Default/Cache",
            ),
            os.path.join(
                "C:/Users/",  # Internet Explorer
                getpass.getuser(),
                r"AppData/Local/Microsoft/Windows/INetCache",
            ),
            os.path.join(
                "C:/Users/",  # Edge
                getpass.getuser(),
                r"AppData/Local/Packages/Microsoft.MicrosoftEdge_8wekyb3d8bbwe/AC/Temp",
            ),
        )

        for folder in folders:
            if os.path.isdir(folder):
                self.task(folder)

        self.logSignal.emit(
            "%d files and %d folders deleted.\n"
            % (self.delete_file_count, self.delete_folder_count)
        )

        self.finished.emit()

    def task(self, folder):
        for file in os.listdir(folder):
            file_path = os.path.join(folder, file)
            print(file_path, file)

            try:

                if os.path.isfile(file_path):
                    os.unlink(file_path)

                    self.logSignal.emit("%s file deleted" % file)
                    self.delete_file_count += 1

                elif os.path.isdir(file_path):
                    if "chocolatey" in file_path:
                        continue
                        shutil.rmtree(file_path)
                        self.logSignal.emit("%s folder deleted" % file)
                        self.delete_folder_count += 1

            except Exception as e:
                self.logSignal.emit("Access Denied: %s" % file)


class TempRemove(QMainWindow, Optimization.Ui_OptimalWindow):
    def __init__(self, parent=None):
        super(QMainWindow, self).__init__(parent)
        self.initUI(self)


if __name__ == "__main__":
    a = QApplication(sys.argv)

    w = TempRemove()
    o = CleanWorker()
    o.started.connect(w.show)
    o.logSignal.connect(w.ScanInfo.append)
    o.clean()

    sys.exit(a.exec_())
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...