拖放事件后更新 PyQT 中的标签文本

Updating label text in PyQT after drag & drop event

我只是在 Python 中速成 UI,但似乎我遇到了这堵有趣的墙,我希望得到一些帮助。

我的代码是:

from PyQt5.QtWidgets import QMainWindow, QApplication
import sys
from subprocess import check_output
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWidgets import * 
from PyQt5.QtGui import * 
from PyQt5 import QtCore, QtGui 
from PyQt5.QtCore import * 
import json
import time


class MainWidget(QMainWindow):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("GAINWARD EDGE Antivirus")
        self.resize(504, 590)
        self.setAcceptDrops(True)
        self.pushButton_2 = QtWidgets.QPushButton(self)
        self.pushButton_2.setGeometry(QtCore.QRect(170, 520, 141, 21))
        self.pushButton_2.setObjectName("pushButton_2")
        self.LFileName = QtWidgets.QLabel(self)
        self.LFileName.setGeometry(QtCore.QRect(210, 50, 91, 21))
        self.LFileName.setFrameShape(QtWidgets.QFrame.StyledPanel)
        self.LFileName.setLineWidth(19)
        self.LFileName.setObjectName("LFileName")
        self.LCrowdStrike = QtWidgets.QLabel(self)
        self.LCrowdStrike.setGeometry(QtCore.QRect(70, 190, 131, 16))
        self.LCrowdStrike.setObjectName("LCrowdStrike")
        self.LHash = QtWidgets.QLabel(self)
        self.LHash.setGeometry(QtCore.QRect(210, 90, 91, 21))
        self.LHash.setFrameShape(QtWidgets.QFrame.StyledPanel)
        self.LHash.setLineWidth(19)
        self.LHash.setObjectName("LHash")
        self.LMetaDefender = QtWidgets.QLabel(self)
        self.LMetaDefender.setGeometry(QtCore.QRect(70, 240, 131, 16))
        self.LMetaDefender.setObjectName("LMetaDefender")
        self.LVirusTotal = QtWidgets.QLabel(self)
        self.LVirusTotal.setGeometry(QtCore.QRect(70, 290, 131, 16))
        self.LVirusTotal.setObjectName("LVirusTotal")
        self.StatCrowd = QtWidgets.QLabel(self)
        self.StatCrowd.setGeometry(QtCore.QRect(260, 180, 111, 41))
        self.StatCrowd.setObjectName("StatCrowd")
        self.StatMeta = QtWidgets.QLabel(self)
        self.StatMeta.setGeometry(QtCore.QRect(260, 230, 111, 41))
        self.StatMeta.setObjectName("StatMeta")
        self.StatVirus = QtWidgets.QLabel(self)
        self.StatVirus.setGeometry(QtCore.QRect(260, 280, 111, 41))
        self.StatVirus.setObjectName("StatVirus")


        self.retranslateUi(self)
        QtCore.QMetaObject.connectSlotsByName(self)


    def retranslateUi(self, Dialog):
        _translate = QtCore.QCoreApplication.translate
        Dialog.setWindowTitle(_translate("Dialog", "Dialog"))
        self.pushButton_2.setText(_translate("Dialog", "Exit"))
        self.LFileName.setText(_translate("Dialog", "FileName"))
        self.LCrowdStrike.setText(_translate("Dialog", "CrowdStrike Falcon:"))
        self.LHash.setText(_translate("Dialog", "Hash"))
        self.LMetaDefender.setText(_translate("Dialog", "Metadefender:"))
        self.LVirusTotal.setText(_translate("Dialog", "VirusTotal:"))
        self.StatCrowd.setText(_translate("Dialog", "Status1"))
        self.StatMeta.setText(_translate("Dialog", "Status2"))
        self.StatVirus.setText(_translate("Dialog", "Status3"))

    def dragEnterEvent(self, event):
        if event.mimeData().hasUrls():
            event.accept()
        else:
            event.ignore()

    def foobar():
        ui.LFileName.setText(f)
        ui.LHash.setText("???")
        ui.StatCrowd.setText(crowdStrikeStatus)
        ui.StatMeta.setText(metaDefenderStatus)
        ui.StatVirus.setText(virusTotalStatus)

    def dropEvent(self, event):
        files = [u.toLocalFile() for u in event.mimeData().urls()]
        for f in files:

            out = check_output(["C:\Users\lilra\AppData\Local\Programs\Python\Python39\python.exe", "C:\Users\lilra\Desktop\dev\pyqt\VxAPI\vxapi.py", "scan_file", f"{f}", "all"])

            crowdStrikeName = json.loads(out)['scanners'][0]['name']
            crowdStrikeStatus = json.loads(out)['scanners'][0]['status']

            if "no-result" in crowdStrikeStatus:
                crowdStrikeStatus = "No detection [OK]"

            print(f"{crowdStrikeName}: {crowdStrikeStatus}")

            metaDefenderName = json.loads(out)['scanners'][1]['name']
            metaDefenderStatus = json.loads(out)['scanners'][1]['status']

            if "clean" in metaDefenderStatus:
                metaDefenderStatus = "No detection [OK]"

            print(f"{metaDefenderName}: {metaDefenderStatus}")

            virusTotalName = json.loads(out)['scanners'][2]['name']
            virusTotalStatus = json.loads(out)['scanners'][2]['status']

            if "no-result" in virusTotalStatus:
                virusTotalStatus = "No detection [OK]"

            print(f"{virusTotalName}: {virusTotalStatus}")


            VirusTotal.setText('Hello, world!')


if __name__ == '__main__':
    app = QApplication(sys.argv)
    ui = MainWidget()
    ui.show()
    splash = QSplashScreen()
    splash.setPixmap(QPixmap('obbac2wjcpvenbtcg8zi.png').scaled(770, 830))
    splash.show()
    splash.showMessage('<h1 style="color:white;">Gainward EDGE Antivirus Initializing...</h1>', 
                       Qt.AlignTop | Qt.AlignHCenter, Qt.white)    
    time.sleep(1)

    splash.hide()

    sys.exit(app.exec_())

所以在 drop 事件之后,它可能应该做这样的事情:

    def foobar():
        ui.LFileName.setText(f)
        ui.LHash.setText("sample API response text")
        ui.StatCrowd.setText(crowdStrikeStatus)
        ui.StatMeta.setText(metaDefenderStatus)
        ui.StatVirus.setText(virusTotalStatus)

但我很难做到这一点。

回顾一下,我在文件的拖放事件后进行 API 调用,然后尝试使用 API 响应的解析结果更新文本标签。

这将有效:

class MainWidget(QMainWindow):
    ...

    def dragLeaveEvent(self, event):
        self.foobar(file_info=('-', '-'))

    def dragEnterEvent(self, event):
        if event.mimeData().hasUrls():
            event.accept()
            file = event.mimeData().urls()[0]
            file_info = self.get_file_info(file=file)
            self.foobar(file_info=file_info)
        else:
            event.ignore()

    @staticmethod
    def get_file_info(file):
        hasher = hashlib.md5()

        with open(file.toLocalFile(), 'rb') as f:
            hasher.update(f.read())

        filename = file.fileName()
        _hash = hasher.hexdigest()
        return filename, _hash
    
    # UPDATE UI
    def foobar(self, file_info):
        self.LFileName.setText(file_info[0])
        self.LHash.setText(file_info[1])