如何使用threading.py 回顾

问题描述

好的,所以我到处都在寻找,是的,有很多很多例子,其中有很多成功使用pyqt5应用程序的QThread或线程技术的人。但是,所有这些示例都是为他们要创建的每个新线程创建线程函数。我没有时间这样做。我正在寻找的是一种具有功能方法,基本上可以执行以下操作:

function(commandToBeStartedInNewThread,argumentsForCommand):
    start(commandToBeStartedInNewThread) #The command will be started in New Thread

对于抱歉的伪代码,我们深表歉意。 :(

我最接近的是使用内置的python Threading模块来实现此功能

def NewThread(com,Returning: bool,*arguments) -> Any:
    """
    Will create a new thread for a function/command.

    :param com: Command to be Executed
    :param Returning: True/False Will command return anything
    :param arguments: Arguments to be sent to Command

    """
    
    class NewThreadWorker(Thread):
        def __init__(self,group = None,target = None,name = None,args = (),kwargs = None,*,daemon = None):
            Thread.__init__(self,group,target,name,args,kwargs,daemon = daemon)
            self.daemon = True
            self._return = None
        
        def run(self):
            if self._target is not None:
                self._return = self._target(*self._args,**self._kwargs)
        
        def join(self):
            Thread.join(self)
            return self._return
    
    ntw = NewThreadWorker(target = com,args = (*arguments,))
    if Returning:
        ntw.start()
        return ntw.join()
    else:
        ntw.start()

上述函数在新线程中启动该函数,但是在pyqt5应用程序中运行时,出现错误提示QObject::startTimer: Timers cannot be started from another thread,然后整个程序崩溃。

对此感到沮丧约2-3个小时后,我在堆栈溢出中发现了一些答案,这说明使用PyQt的QThread模块更容易做到这一点。所以我尝试了一下。这是我目前拥有的:

(请注意,我不太了解这一工作原理。另外,我对PyQt信号/插槽系统的了解非常少)

def NewQThread(com):
    class CreateQThread(QThread):
        
        def __init__(self,command,*args,**kwargs):
            QThread.__init__(self)
            
            self.command = command
            self.args = args
            self.kwargs = kwargs
            
        def run(self):
            self.command(*self.args,**self.kwargs)
        
    StartThread = CreateQThread(com)
    StartThread.start()

QThread函数执行在新线程中启动该函数。但是一旦它通过了它的基本部分就会崩溃。

这是我总共拥有的,因此您可以自己进行测试:

main.py

import configparser
import os
import sys
from pathlib import Path
from platform import uname
from threading import Thread
from typing import Any
from sys import platform
import subprocess as sub

from PyQt5 import QtGui
from PyQt5.QtWidgets import QMainWindow,QApplication,QMessageBox,QDialog,QFileDialog
from PyQt5.QtCore import QThread,Qt,pyqtSignal,pyqtSlot,QObject,QTimer,QEventLoop

from hashgen import Ui_hashGEN
from mainUI import Ui_MainWindow


def NewThread(com,))
    if Returning:
        ntw.start()
        return ntw.join()
    else:
        ntw.start()


def NewQThread(com,**kwargs):
    class CreateQThread(QThread):
        
        def __init__(self,**kwargs):
            QThread.__init__(self)
            self.timer = QTimer()
            self.timer.movetoThread(self)
            
            self.command = command
            self.args = args
            self.kwargs = kwargs
        
        def run(self):
            self.command(*self.args,**self.kwargs)
            loop = QEventLoop()
            loop.exec_()
    
    x = CreateQThread(com,**kwargs)
    x.start()



def hashCheck():
    class hashRUN(QDialog,Ui_hashGEN):
        
        hash_number = 0
        
        def __init__(self,parent = None):
            super(hashRUN,self).__init__(parent)
            self.setwindowIcon(QtGui.QIcon(':/Pictures/images/cup2.png'))
            self.setFixedSize(431,179)
            self.setupUi(self)
            
            def fileselection():
                dialog = QFileDialog.getopenFileName(self,'Select file')
                self.fpath.setText(dialog[0])
                print(dialog[0])
            
            self.browsebutton.clicked.connect(fileselection)
            
            def hashMD5(selected):
                if selected:
                    self.hash_number = 0
            
            def hashsha1(selected):
                if selected:
                    self.hash_number = 1
            
            def hashsha256(selected):
                if selected:
                    self.hash_number = 2
            
            def hashsha384(selected):
                if selected:
                    self.hash_number = 3
            
            def hashsha512(selected):
                if selected:
                    self.hash_number = 4
            
            self.MD5radio.toggled.connect(hashMD5)
            self.SHA1radio.toggled.connect(hashsha1)
            self.SHA256radio.toggled.connect(hashsha256)
            self.SHA384radio.toggled.connect(hashsha384)
            self.SHA512radio.toggled.connect(hashsha512)
            
            def OUTPUTBox(text):
                OUTPUT = QMessageBox()
                OUTPUT.setwindowTitle('hey! Listen!')
                OUTPUT.setText(
                    "Hash has been successfully created.\nYou can copy the hash in Details.\n\n" + text)
                OUTPUT.setDetailedText(text)
                OUTPUT.setIcon(QMessageBox.@R_327_4045@ion)
                OUTPUT.setwindowIcon(QtGui.QIcon(':/Pictures/images/hey.png'))
                OUTPUT.exec_()
            
            def hashchk(hash_number):
                if len(self.fpath.text()) != 0 and Path(self.fpath.text()).is_file():
                    linux_hash_types = ['md5sum','sha1sum','sha256sum','sha384sum','sha512sum']
                    windows_hash_types = ['MD5','SHA1','SHA256','SHA384','SHA512']
                    darwin_hash_types = ['md5','shasum -a 1','shasum -a 256','shasum -a 384','shasum -a 512']
                    
                    if platform == 'linux':
                        filepath = self.fpath.text()
                        command = r'sudo ' + linux_hash_types[hash_number] + ' ' + filepath
                        EXEC = sub.Popen(command.split(),stdout = sub.PIPE)
                        stdout,_ = EXEC.communicate()
                        output = stdout.decode("utf-8")
                        OUTPUTBox(output)
                    elif platform == 'darwin':
                        filepath = self.fpath.text()
                        command = r'sudo ' + darwin_hash_types[hash_number] + ' ' + filepath
                        EXEC = sub.Popen(command.split(),_ = EXEC.communicate()
                        output = stdout.decode("utf-8")
                        OUTPUTBox(output)
                    elif platform == 'win32':
                        filepath = self.fpath.text()
                        EXEC = sub.Popen(["powershell","& {Get-filehash '" + filepath + "' -Algorithm " +
                                        windows_hash_types[hash_number] + " | Format-List}"],_ = EXEC.communicate()
                        output = stdout.decode("utf-8")
                        OUTPUTBox(output)
                elif len(self.fpath.text()) == 0:
                    print('No file path entered')
                    ERROR_NO_FILEPATH = QMessageBox()
                    ERROR_NO_FILEPATH.setIcon(QMessageBox.Warning)
                    ERROR_NO_FILEPATH.setwindowTitle('hey! Listen!')
                    ERROR_NO_FILEPATH.setText(
                        'ERROR: No File Path Found')
                    ERROR_NO_FILEPATH.setStandardButtons(QMessageBox.Close)
                    ERROR_NO_FILEPATH.setwindowIcon(QtGui.QIcon(':/Pictures/images/hey.png'))
                    ERROR_NO_FILEPATH.exec_()
                elif not Path(self.fpath.text()).is_file():
                    print('No file path entered')
                    ERROR_FILE_NOT_FOUND = QMessageBox()
                    ERROR_FILE_NOT_FOUND.setIcon(QMessageBox.Warning)
                    ERROR_FILE_NOT_FOUND.setwindowTitle('hey! Listen!')
                    ERROR_FILE_NOT_FOUND.setText(
                        'ERROR: File Not Found Or Does Not Exist')
                    ERROR_FILE_NOT_FOUND.setStandardButtons(QMessageBox.Close)
                    ERROR_FILE_NOT_FOUND.setwindowIcon(QtGui.QIcon(':/Pictures/images/hey.png'))
                    ERROR_FILE_NOT_FOUND.exec_()
            
            self.genhash.clicked.connect(lambda: hashchk(self.hash_number))
    
    widget = hashRUN()
    widget.exec_()



class Main_start(QMainWindow,Ui_MainWindow):
    
    
    
    def __init__(self,parent = None):
        super(Main_start,self).__init__(parent)
        print('Script Runner has started')
        self.setFixedSize(860,675)
        self.setupUi(self)
        self.setwindowIcon(QtGui.QIcon(':/Pictures/images/cup2.png'))
        self.mmfuncassign()
    
    def mmfuncassign(self):
        print('Assigning functions')
        
        self.header_title.setWordWrap(True)
        self.descriptions.setWordWrap(True)
        
        
        def quitButton():
            print('Closing program')
            sys.exit(0)
        
        def display(i):
            if i == 0:
                self.header_title.setText('Universal Commands')
                self.descriptions.setText(
                    'Description: These commands will work on most Operating Systems\nE.g. Windows,MacOS X,and Linux (Debian,Ubuntu,certain Arch distros)')
                self.stackedWidget.setCurrentIndex(i)
            elif i == 1:
                if uname()[0] == 'Windows':
                    self.header_title.setText('Windows 10 Commands')
                    self.descriptions.setText(
                        'Description: These commands will work on the following Windows systems: 10,8.x,and 7')
                    self.stackedWidget.setCurrentIndex(i)
            elif i == 2:
                if uname()[0] == 'Linux':
                    self.header_title.setText('Linux Commands')
                    self.descriptions.setText(
                        'Description: These commands will work on the following Linux systems: Debian based systems,and manjaro')
                    self.stackedWidget.setCurrentIndex(i)
            elif i == 3:
                if uname()[0] == 'Darwin':
                    self.header_title.setText('MacOS X Commands')
                    self.descriptions.setText(
                        'Description: These commands will ONLY work on MacOS X')
                    self.stackedWidget.setCurrentIndex(i)
        
        display(0)
        
        def Button_Connect():
            self.uniCom.clicked.connect(lambda: display(0))
            self.winCom.clicked.connect(lambda: display(1))
            self.linCom.clicked.connect(lambda: display(2))
            self.macCom.clicked.connect(lambda: display(3))
            
            # Universal Buttons
            self.chkhashfile_buttonUNI.clicked.connect(lambda: NewThread(hashCheck,False))
            
            self.quit_button_3.clicked.connect(quitButton)
        
        Button_Connect()


if __name__ == "__main__":
    QApplication.setAttribute(Qt.AA_EnableHighDpiScaling,True)
    QApplication.setAttribute(Qt.AA_UseHighDpipixmaps,True)
    app = QApplication(sys.argv)
    main = Main_start()
    main.show()
    sys.exit(app.exec_())

mainUI.py(从链接复制)

raw code here

hashgen.py(从链接复制)

raw code here

resources_rc.py(从链接复制)

raw code here

回顾

回顾一下,我试图制作一个NewThread函数,您要做的就是将要在newthread中启动的命令/函数输入到NewT​​hread函数中,但是我遇到了错误

任何帮助将不胜感激! (对不起所有意大利面条代码

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)