如何在pysimplegui中仅显示所选文件名,并在前面使用文本标签

0 投票
3 回答
32 浏览
提问于 2025-04-12 13:58

这是我第一次尝试使用pysimplegui来做一个应用程序。在此之前,我一直在用tkinter,但那个界面看起来不够美观和现代。

我想做的是创建一个窗口,里面有三个按钮:两个用来选择不同的文件,一个用来启动比较功能。选择文件后,我只想让界面显示文件名。如果我添加一个sg.Text(),它会显示完整的文件路径,但我只想给用户显示文件名。

以下是我遇到问题的最简代码:

import PySimpleGUI as sg
import os

# layout = [
#     [sg.InputText(size=(45, 1), key="File_1", disabled=True), sg.FileBrowse(enable_events=True, key="File_path_1", target=(0, 1))],
#     [sg.InputText(size=(45, 1), key="File_2", disabled=True), sg.FileBrowse(enable_events=True, key="File_path_2", target=(1, 1))],
#     [sg.Submit()]
#         ]

layout = [
    [sg.Text('Old_file '), sg.InputText(size=(45, 1), key="File_1", disabled=True), sg.FileBrowse(enable_events=True, key="File_path_1", target=(0, 1))],
    [sg.Text('New_file'), sg.InputText(size=(45, 1), key="File_2", disabled=True), sg.FileBrowse(enable_events=True, key="File_path_2", target=(1, 1))],
    [sg.Submit()]
        ]
window = sg.Window("File compare", layout)


while True:
    event, values = window.read()
    if event is None or event == "Cancel":
        break
    elif event == "File_path_1":
        filepath = values.get('File_path_1')
        window['File_1'].update(os.path.basename(filepath))
    elif event == "File_path_2":
        filepath = values.get('File_path_2')
        window['File_2'].update(os.path.basename(filepath))
    elif event == 'Submit':
        print("hello")

这是我在布局中看到的带有文本标签的效果图: 在这里输入图片描述

我的问题是,如何让它只显示文件名,即使在文件名文本框前面有文本标签。当我在sg.InputText()之前添加一个sg.Text()元素时,它显示的是文件路径,而不是我最初想要的文件名。我以为使用key可以只更新界面的某一部分,但当sg.Text()元素在我想用文件名更新的InputText之前时,它并没有按我想的那样工作,而是显示了文件路径。

补充:我使用的是PySimpleGUI-4-foss==4.60.4.1这个包,而不是PysimpleGUI v5.0.3。感谢Mimo的快速回复。

3 个回答

0

你可以通过以下方式来实现:

  • 使用函数 popup_get_file 来获取文件名
  • 使用属性 element.metadata 来保存文件的完整路径
  • 使用函数 os.path.basename 来获取基本的文件名。
import os
import PySimpleGUI as sg

font = ("Courier New", 12)
sg.set_options(font=font)

layout = [
    [sg.Text("Old File"), sg.Input(disabled=True, key="OLD", metadata=""), sg.Button("Browse", key="Browse OLD")],
    [sg.Text("New File"), sg.Input(disabled=True, key="NEW", metadata=""), sg.Button("Browse", key="Browse NEW")],
    [sg.Push(), sg.Button("Submit"), sg.Push()],
]
window = sg.Window("Title", layout)

while True:

    event, values = window.read()

    if event == sg.WIN_CLOSED:
        break

    if event.startswith("Browse"):
        _, key = event.split(" ")
        full_path = sg.popup_get_file("Filename", no_window=True)
        if full_path:
            window[key].metadata = full_path
            window[key].update(os.path.basename(full_path))

window.close()
1
while True:
    event, values = window.read()
    if event is None or event == "Cancel":
        break
    elif event == "File_path_1":
        filepath = values.get('File_path_1')
        window['File_1'].update(os.path.basename(filepath))
    elif event == "File_path_2":
        filepath = values.get('File_path_2')
        window['File_2'].update(os.path.basename(filepath))
    elif event == 'Submit':
        print("hello")

os.path.basename() 这个方法来代替 split() 方法,因为 split() 会返回一个元组。

1

非常抱歉出现了这个问题,不知道为什么第一次能正常工作。这是一个更新版本。

import PySimpleGUI as sg
import os

layout = [
    [sg.Text('Old_file '), sg.Input(size=(45, 1), key="File_1", readonly=True), sg.FileBrowse(target='Hidden_Browse_1', key='Browse_1', enable_events=True), sg.In(visible=False, enable_events=True, key='Hidden_Browse_1')],
    [sg.Text('New_file'), sg.Input(size=(45, 1), key="File_2", readonly=True), sg.FileBrowse(target='Hidden_Browse_2', key='Browse_2', enable_events=True), sg.In(visible=False, enable_events=True, key='Hidden_Browse_2')],
    [sg.Submit()]
]

window = sg.Window("File compare", layout)

while True:
    event, values = window.read()
    if event is None or event == "Cancel":
        break
    elif event == "Hidden_Browse_1":
        filepath = values.get('Hidden_Browse_1')
        window['File_1'].update(os.path.basename(filepath))
    elif event == "Hidden_Browse_2":
        filepath = values.get('Hidden_Browse_2')
        window['File_2'].update(os.path.basename(filepath))
    elif event == 'Submit':
        print("hello")

我为造成的困惑道歉。sg.popup_get_file() 这个函数会打开一个文件选择对话框,所以当你点击浏览按钮时,会看到两个文件对话框。

要解决这个问题,你可以使用 sg.FileBrowse 按钮,并把 target 参数设置为一个隐藏的 sg.Input 输入框。然后,在你的事件循环中,可以用文件名更新可见的 sg.Input 输入框。

下面是具体的做法:

import PySimpleGUI as sg
import os

layout = [
    [sg.Text('Old_file '), sg.Input(size=(45, 1), key="File_1", readonly=True), sg.FileBrowse(target='Hidden_Browse_1', key='Browse_1', enable_events=True), sg.In(visible=False, enable_events=True, key='Hidden_Browse_1')],
    [sg.Text('New_file'), sg.Input(size=(45, 1), key="File_2", readonly=True), sg.FileBrowse(target='Hidden_Browse_2', key='Browse_2', enable_events=True), sg.In(visible=False, enable_events=True, key='Hidden_Browse_2')],
    [sg.Submit()]
]

window = sg.Window("File compare", layout)

while True:
    event, values = window.read()
    if event is None or event == "Cancel":
        break
    elif event == "Hidden_Browse_1":
        filepath = values.get('Hidden_Browse_1')
        window['File_1'].update(os.path.basename(filepath))
    elif event == "Hidden_Browse_2":
        filepath = values.get('Hidden_Browse_2')
        window['File_2'].update(os.path.basename(filepath))
    elif event == 'Submit':
        print("hello")

sg.FileBrowse 按钮的目标是隐藏的 sg.Input 输入框。当选择了一个文件后,隐藏的 sg.Input 输入框会更新为完整的文件路径,并触发一个事件。接着,在你的事件循环中,你可以从隐藏的 sg.Input 输入框中获取文件路径,使用 os.path.basename() 获取文件名,并用这个文件名更新可见的 sg.Input 输入框。

截图

撰写回答