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

Posted

技术标签:

【中文标题】如何更改标签以使用 PyQt5 显示文件路径?【英文标题】:How can I change the label to display the file path with PyQt5? 【发布时间】:2017-06-16 03:25:05 【问题描述】:

我想更改 QLabel 类中 Label 小部件的文本,以显示用户在单击按钮以打开文件对话框以从计算机中选择图像时选择的图像文件的文件路径。代码如下:

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() 类。我尝试混合使用 TkInter 和 PyQt5 来满足这个要求,但这只会引发更多错误。

【问题讨论】:

我是否应该把这个问题也扔到 ux.stackexchange.com 上,即使该网站上只有一个关于 PyQt 的问题? 不——你的问题与用户体验设计没有任何关系。 【参考方案1】:

在您的情况下,您应该能够访问变量 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.

【讨论】:

非常感谢。我花了很多时间玩这个,但我一直无法弄清楚。我来自 Java 背景,但我在大学课程中学习了 Java 7,而且我的导师们对 lambda 的概念不屑一顾,因为我在课程中是可选的,所以我以前从未使用过 lambda 表达式。

以上是关于如何更改标签以使用 PyQt5 显示文件路径?的主要内容,如果未能解决你的问题,请参考以下文章

使用PyQt5 for Python gui的可滚动标签

如何在 python 中使用 pyqt5 显示 2 个按钮和 2 个标签?

PyQt5控制 窗口和显示窗口

PyQt5 Resize 应用程序以适应不同的显示器

如何在每个 Qlabel PyQt5 中显示两个图像

PyQt5调整应用程序以适应不同的显示