如何更改标签以使用 PyQt5 显示文件路径?

How can I change the label to display the file path with PyQt5?

我想更改 QLabel 的 Label 小部件的文本 class 以显示用户在单击按钮打开文件对话框以选择图像时选择的图像文件的文件路径来自他们电脑的图像。这是代码:

class GUI(QMainWindow):
    #Load the GUI.
    def __init__(self):
        super().__init__()

        #Define the window icon.
        self.window_icon = QIcon("LightMap.png")

        #Make the UI.
        self.init_ui()

    #Fill the GUI.
    def init_ui(self):
        #Load the UI file.
        main_window = uic.loadUi("mainwindow.ui", self)

        #Set the window icon.
        self.setWindowIcon(self.window_icon)

        #Add commands for actions under the submenus.
        self.command_file_menu(main_window)
        self.command_settings_menu(main_window)
        self.command_help_menu(main_window)

        #Handle the case that the user clicks on the "Open Image" button.
        main_window.button_open_image.setStatusTip("Open Image")
        main_window.button_open_image.clicked.connect(self.open_file)

        #Make sure this variable has been declared so that we can click "Start Mapping" at any time.
        self.file_chosen = None

        #Handle the case that the user clicks on the "Start Mapping" button.
        main_window.button_start_mapping.setStatusTip("Start Mapping")
        main_window.button_start_mapping.clicked.connect(self.start_mapping)

        #Show the main window.
        self.show()

    #Add commands for actions under the File menu.
    def command_file_menu(self, main_window):
        #Back-end logic for Open Image.
        main_window.action_open_image.setShortcut("CTRL+O")
        main_window.action_open_image.setStatusTip("Open Image")
        main_window.action_open_image.triggered.connect(self.open_file)

    #Open an image file.
    def open_file(self):
        #Select the file dialog design.
        dialog_style = QFileDialog.DontUseNativeDialog
        dialog_style |= QFileDialog.DontUseCustomDirectoryIcons

        #Open the file dialog to select an image file.
        self.file_chosen, _ = QFileDialog.getOpenFileName(self, "QFileDialog.getOpenFileName()", "",
            "JPEG (*.JPEG *.jpeg *.JPG *.jpg *.JPE *.jpe *JFIF *.jfif);; PNG (*.PNG *.png);; GIF (*.GIF *.gif);; Bitmap Files (*.BMP *.bmp *.DIB *.dib);; TIFF (*.TIF *.tif *.TIFF *.tiff);; ICO (*.ICO *.ico)", options=dialog_style)

        #Show the path of the file chosen.
        if self.file_chosen:
            #Change the text on the label to display the file path chosen.
        else:
            #Change the text on the label to say that "No file was selected. Please select an image."
            #This 'else' statement is used to catch the case where the user presses 'Cancel' after opening the file dialog,
            #which will close the file dialog without choosing any file, even if they had already previously chosen a file
            #from previously opening the file dialog.


if __name__ == "__main__":
    app = QApplication(sys.argv)
    ex = GUI()
    sys.exit(app.exec_())

我已经尝试直接将 main_window 传递给 open_file() 并直接设置标签文本,如下所示:main_window.label_file_name.setText(self.file_chosen),但是当我启动 GUI 时文件对话框立即打开错误 TypeError: argument1 has unexpected type NoneType.

我设法让这个功能与 TkInter 一起工作,但我一直无法弄清楚如何将这个功能重复到 PyQt5。这是我的工作 TkInter 代码的示例:

class GUI:    
    #Structure the GUI.
    def __init__(self):

        #Create a blank window.
        self.root = Tk()

        #Create the frame.
        frameRoot = Frame(self.root)
        frameRoot.pack()

        #Create the menu.
        menu = Menu(self.root)
        self.root.config(menu=menu)

        #Create the "File" submenu.
        fileMenu = Menu(menu, tearoff=0)
        menu.add_cascade(label="File", menu=fileMenu)
        fileMenu.add_command(label="Open Image", command=self.openFile)

        #Make a button to open the image file.
        self.fileChosen = None #Prevent the user from mapping without first selecting an image.
        self.buttonFile = Button(frameRoot, text="Open Image...", command=self.openFile)
        self.buttonFile.grid(row=3, column=1)

        #Display the directory path of the file chosen.
        self.fileName = StringVar()
        self.fileName.set("No File Selected")
        self.labelFileName = Label(frameRoot, textvariable=self.fileName, fg="red")
        self.labelFileName.grid(row=4, column=1)

        #Keep the window open.
        self.root.mainloop()

    #Open the image file.
    def openFile(self):
        #Only accept the following file types.
        self.fileChosen = filedialog.askopenfilename(filetypes=[("Bitmap Files", "*.BMP *.bmp *.DIB *.dib"),
                                                              ("JPEG", "*.JPEG *.jpeg *.JPG *.jpg *.JPE *.jpe *JFIF *.jfif"),
                                                              ("PNG", "*.PNG *.png"),
                                                              ("GIF", "*.GIF *.gif"),
                                                              ("TIFF", "*.TIF *.tif *.TIFF *.tiff"),
                                                              ("ICO", "*.ICO *.ico")
                                                             ])

        #If a file was selected, show the file path. Else, inform the user.
        if self.fileChosen:
            self.fileName.set(self.fileChosen)
        else:
            self.fileName.set("No image was selected. Please select an image.")

if __name__ == "__main__":
    #Create an object to access the class.
    g = GUI()

我的 TkInter 实现成功的关键是使用来自 TkInter 的 StringVar() class。我已经尝试混合使用 TkInter 和 PyQt5 来满足这个要求,但这只会引发更多错误。

在你的情况下你应该能够访问变量 main_window 因为它允许我访问标签,为此你必须将它作为参数传递,所以我建议你使用 lambda 函数并将您的代码修改为:

    [...]
    main_window.button_open_image.clicked.connect(lambda: self.open_file(main_window))

#Open an image file.
def open_file(self, main_window):
    #Select the file dialog design.
    dialog_style = QFileDialog.DontUseNativeDialog
    dialog_style |= QFileDialog.DontUseCustomDirectoryIcons

    #Open the file dialog to select an image file.
    self.file_chosen, _ = QFileDialog.getOpenFileName(self, "QFileDialog.getOpenFileName()", "",
        "JPEG (*.JPEG *.jpeg *.JPG *.jpg *.JPE *.jpe *JFIF *.jfif);; PNG (*.PNG *.png);; GIF (*.GIF *.gif);; Bitmap Files (*.BMP *.bmp *.DIB *.dib);; TIFF (*.TIF *.tif *.TIFF *.tiff);; ICO (*.ICO *.ico)", options=dialog_style)

    #Show the path of the file chosen.
    if self.file_chosen:
        main_window.label_file_name.setText(self.file_chosen)
        #Change the text on the label to display the file path chosen.
    else:
        main_window.label_file_name.setText("No file was selected. Please select an image.")
        #Change the text on the label to say that "No file was selected. Please select an image."
        #This 'else' statement is used to catch the case where the user presses 'Cancel' after opening the file dialog,
        #which will close the file dialog without choosing any file, even if they had already previously chosen a file
        #from previously opening the file dialog.