QWidget:必须在QWidget之前构造QApplication,而不在该特定文件中使用QWidget

2024-04-19 19:45:56 发布

您现在位置:Python中文网/ 问答频道 /正文

我有三个文件(GUI.py、encrypt.py、filebrowser.py)。通过GUI,用户单击打开文件浏览器的“搜索”按钮。他选择一个文件并点击“加密”对其进行加密。只要我在GUI.py中导入了encrypt.py,我就会得到错误“QWidget:必须在QWidget之前构造QApplication”,所以我猜错误在encrypt.py中。但是在encrypt.py中,我不使用任何PyQt,我只是从filebrowser.py中获取一个变量的文件名,它确实使用PyQt。有人有什么建议吗

filebrowser.py:

    import sys
    from PyQt5.QtWidgets import QApplication, QWidget, QInputDialog, QLineEdit, QFileDialog
    from PyQt5.QtGui import QIcon
    
    class App(QWidget): #unencrypted
    
        def __init__(self):
            super().__init__()
            self.title = 'PyQt5 file dialog'
            self.left = 10
            self.top = 10
            self.width = 640
            self.height = 480
            self.initUI()
        
        def initUI(self):
            self.setWindowTitle(self.title)
            self.setGeometry(self.left, self.top, self.width, self.height)
            
            self.openFileNameDialog()
            #self.openFileNamesDialog()
            #self.saveFileDialog()
            
            self.show()
        
        def openFileNameDialog(self):
            global fileName
            options = QFileDialog.Options()
            options |= QFileDialog.DontUseNativeDialog
            fileName = QFileDialog.getOpenFileName(self,"Choose file to encrypt", "./","All Files (*);;Python Files (*.py)", options=options)
            if fileName:
                return(fileName)
    
    if __name__ == '__main__':
        app = QApplication(sys.argv)
        ex = App()
        sys.exit(app.exec_())

encrypt.py:

    import os
    from filebrowser import App import filebrowser as FB
    
class App1(object):

    def encrypt(filename:str = None):
        if filename is None:
            filename = FB.App().openFileNameDialog()
        to_encrypt = open(filename, "rb").read()
        size = len(to_encrypt)
        key = os.urandom(size)
        with open(filename + ".key", "wb") as key_out:
            key_out.write(key)
            encrypted = bytes(a^b for (a,b) in zip(filename, key))
        with open(filename, "wb") as encrypted_out:
            encrypted_out.write(encrypted)
        encrypt(filename=FB.App().openFileNameDialog())

GUI.py是主文件:

import sys
from filebrowser import App, App2, App3 
import filebrowser as FB 
from encrypt import App1
import encrypt as EN
from PyQt5 import QtCore, QtGui, QtWidgets




class Ui_MainWindow(object):

    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(805, 568)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.EncryptButton = QtWidgets.QPushButton(self.centralwidget)
        self.EncryptButton.setGeometry(QtCore.QRect(100, 210, 151, 111))
        self.EncryptButton.setObjectName("EncryptButton")
        self.DecryptButton = QtWidgets.QPushButton(self.centralwidget)
        self.DecryptButton.setGeometry(QtCore.QRect(550, 210, 151, 111))
        self.DecryptButton.setObjectName("DecryptButton")
        self.ChooseKeyButton = QtWidgets.QPushButton(self.centralwidget)
        self.ChooseKeyButton.setGeometry(QtCore.QRect(320, 210, 151, 111))
        self.ChooseKeyButton.setObjectName("ChooseKeyButton")
        self.InstructionsText = QtWidgets.QPlainTextEdit(self.centralwidget)
        self.InstructionsText.setGeometry(QtCore.QRect(100, 400, 601, 161))
        self.InstructionsText.setObjectName("InstructionsText")
        self.ChooseUnencryptedButton = QtWidgets.QPushButton(self.centralwidget)
        self.ChooseUnencryptedButton.setGeometry(QtCore.QRect(100, 130, 151, 50))
        self.ChooseUnencryptedButton.setObjectName("ChooseUnencryptedButton")
        self.ChooseDecryptedButton = QtWidgets.QPushButton(self.centralwidget)
        self.ChooseDecryptedButton.setGeometry(QtCore.QRect(550, 130, 151, 50))
        self.ChooseDecryptedButton.setObjectName("ChooseDecryptedButton")
        self.NameLabel = QtWidgets.QLabel(self.centralwidget)
        self.NameLabel.setGeometry(QtCore.QRect(340, 30, 141, 51))
        font = QtGui.QFont()
        font.setPointSize(20)
        self.NameLabel.setFont(font)
        self.NameLabel.setObjectName("NameLabel")
        MainWindow.setCentralWidget(self.centralwidget)

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


    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
        self.EncryptButton.setText(_translate("MainWindow", "Encrypt"))
        self.DecryptButton.setText(_translate("MainWindow", "Decrypt"))
        self.ChooseKeyButton.setText(_translate("MainWindow", "Choose key"))
        self.InstructionsText.setPlainText(_translate("MainWindow", "Encrypt: click \"Choose unencrypted file\", choose your file, click \"Encrypt\"\n"
"\n"
"Decrypt: click choose key (filename+.key), choose your key, click \"Choose encrypted file\", choose your file, click \"Decrypt\""))
        self.ChooseUnencryptedButton.setText(_translate("MainWindow", "Choose unencrypted file"))
        self.ChooseDecryptedButton.setText(_translate("MainWindow", "Choose encrypted file"))
        self.NameLabel.setText(_translate("MainWindow", "Encrypt0r"))

if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)
    MainWindow = QtWidgets.QMainWindow()
    ui = Ui_MainWindow()
    ui.setupUi(MainWindow)
    ui.ChooseUnencryptedButton.clicked.connect(FB.App) 
    ui.ChooseKeyButton.clicked.connect(FB.App2)  
    ui.ChooseDecryptedButton.clicked.connect(FB.App3) 
    ui.EncryptButton.clicked.connect(EN.App1) 
    MainWindow.show()
    sys.exit(app.exec_())

编辑: 由于filebrowser.py不是主文件,我编辑了if __name__...部分并更正了缩进

import sys
from PyQt5.QtWidgets import QApplication, QWidget, QInputDialog, QLineEdit, QFileDialog
from PyQt5.QtGui import QIcon

app = QApplication(sys.argv)

class App(QWidget):  # unencrypted
    def __init__(self):
        super().__init__()
        self.title = "PyQt5 file dialog"
        self.left = 10
        self.top = 10
        self.width = 640
        self.height = 480
        self.initUI()

    def initUI(self):
        self.setWindowTitle(self.title)
        self.setGeometry(self.left, self.top, self.width, self.height)

        self.openFileNameDialog()
        # self.openFileNamesDialog()
        # self.saveFileDialog()

        self.show()

    def openFileNameDialog(self):
        options = QFileDialog.Options()
        options |= QFileDialog.DontUseNativeDialog
        fileName = QFileDialog.getOpenFileName(
            self,
            "Choose file to encrypt",
            "./",
            "All Files (*);;Python Files (*.py)",
            options=options,
        )
        if fileName:
            return fileName

ex = App()
sys.exit(app.exec_())

要解决QApplication问题,encrypt.py现在如下所示:

import os
import sys
from PyQt5.QtWidgets import QApplication, QWidget
from filebrowser import App
import filebrowser as FB

app = QApplication(sys.argv)  


class App1(object):

    def encrypt(filename:str = None):
        if filename is None:
            filename = FB.App().openFileNameDialog()
        to_encrypt = open(filename, "rb").read()
        size = len(to_encrypt)
        key = os.urandom(size)
        with open(filename + ".key", "wb") as key_out:
            key_out.write(key)
            encrypted = bytes(a^b for (a,b) in zip(filename, key))
        with open(filename, "wb") as encrypted_out:
            encrypted_out.write(encrypted)

    encrypt(filename = FB.App().openFileNameDialog())

sys.exit(app.exec_())

Windows10,Python 3.9.7,PyQT5版本5.15.4,https://github.com/KDropZ/otp


Tags: keyfrompyimportselfappdefsys