PySimpleGUI - 窗口类



弹出窗口具有预定义的按钮、文本标签和文本输入字段配置。窗口类允许您设计更灵活的 GUI。除了这些元素之外,还提供了其他元素,例如列表框、复选框、单选按钮等。您还可以为 GUI 提供菜单系统。某些专门的小部件(例如微调器、滑块等)也可以用来使设计更有效。

窗口可以是非持久性窗口,类似于弹出窗口。它会阻塞程序流程,直到用户通过单击客户端区域上的按钮或标题栏中的关闭 (X) 按钮关闭它。

另一方面,持久性窗口会一直可见,直到发生导致其关闭的事件。异步窗口是指其内容会定期更新的窗口。

布局结构

窗口客户端区域中元素或小部件的放置由列表列表对象控制。每个列表元素对应窗口表面上的一行,并且可能包含 PySimpleGUI 库中提供的的一个或多个 GUI 元素。

第一步是通过绘制以下图形来可视化元素的放置位置:

Layout

窗口上的元素放置在四行中。前三行有一个文本元素(显示静态文本)和一个输入文本元素(用户可以在其中输入)。最后一行有两个按钮,确定和取消。

这在列表列表中表示如下:

import PySimpleGUI as psg
layout = [
   [psg.Text('Name '),psg.Input()],
   [psg.Text('Address '), psg.Input()],
   [psg.Text('Email ID '), psg.Input()],
   [psg.OK(), psg.Cancel()]
]

此列表对象用作窗口类构造函数的 layout 参数的值。

window = psg.Window('Form', layout)

这将显示所需的窗口。用户输入存储在名为 values 的字典中。当用户按下确定按钮时,会调用窗口类的 read() 方法,窗口立即关闭。

呈现窗口的完整代码如下:

import PySimpleGUI as psg
psg.set_options(font=('Arial Bold', 16))
layout = [
   [psg.Text('Name ', size=(15,1)),psg.Input(expand_x=True)],
   [psg.Text('Address ', size=(15,1)), psg.Input(expand_x=True)],
   [psg.Text('Email ID ', size=(15,1)), psg.Input(expand_x=True)],
   [psg.OK(), psg.Cancel()]
]
window = psg.Window('Form', layout, size=(715,207))
event, values = window.read()
print (event, values)
window.close()

以下是显示的 输出

Layout Structure

按所示输入数据,然后按“确定”按钮。值将打印如下:

OK {0: 'Kiran Gupta', 1: 'Mumbai', 2: '[email protected]'}

如果在填充数据后,您按下“取消”按钮,则打印的结果将为:

Cancel {0: 'Kiran Gupta', 1: 'Mumbai', 2: '[email protected]'}

持久性窗口

请注意,此窗口在任何按钮(或标题栏中的“X”按钮)被点击后立即关闭。为了使窗口保持活动状态,直到按下称为退出的一种特殊类型的按钮或通过按下“X”关闭窗口,read() 方法被放置在一个无限循环中,并在发生 WIN_CLOSED 事件(当按下退出按钮时)或退出事件(当按下“X”按钮时)时提供断开功能。

让我们将上述代码中的取消按钮更改为退出按钮。

import PySimpleGUI as psg
layout = [
   [psg.Text('Name '), psg.Input()],
   [psg.Text('Address '), psg.Input()],
   [psg.Text('Email ID '), psg.Input()],
   [psg.OK(), psg.Exit()]
]
window = psg.Window('Form', layout)
while True:
   event, values = window.read()
   if event == psg.WIN_CLOSED or event == 'Exit':
      break
   print (event, values)
window.close()

窗口的外观将与以前类似,只是取消按钮被替换为退出按钮。

Persistent Window

输入的数据将以元组的形式打印。第一个元素是事件,即按钮的标题,第二个是字典,其键是递增的数字,值是输入的文本。

OK {0: 'kiran', 1: 'Mumbai', 2: '[email protected]'}
OK {0: 'kirti', 1: 'Hyderabad', 2: '[email protected]'}
OK {0: 'karim', 1: 'Chennai', 2: '[email protected]'}

窗口方法

窗口类中定义的重要方法是 read() 方法,用于收集所有输入元素中输入的值。窗口类还有其他方法可以自定义外观和行为。它们列在下面:

序号 方法和描述
1 AddRow

将一行元素添加到窗口的“self.Rows”变量中

2 AddRows

循环遍历元素的列表列表,并将每一行(列表)添加到布局中。

3 close

关闭窗口,以便正确释放资源。

4 disable

禁用窗口,使其无法接收用户的任何输入

5 disappear

使窗口从屏幕上“消失”,但保留在任务栏上。

6 enable

重新启用窗口以接收用户输入

7 fill

使用作为字典提供的数据填充作为输入字段的元素。

8 find_element

查找与提供的键关联的元素对象。它等效于“element = window[key]”

9 get_screen_dimensions

获取屏幕尺寸。

10 hide

隐藏屏幕和任务栏中的窗口

11 load_from_disk

从“SaveToDisk”函数创建的 Pickle 文件中恢复值

12 layout

使用小部件列表列表填充窗口。

13 read

从窗口获取所有数据。传入超时时间(以毫秒为单位)以等待。

14 reappear

使消失的窗口再次显示。

15 save_to_disk

将每个输入元素中包含的值保存到 pickle 文件中。

16 set_title

更改任务栏中窗口的标题

使用键更新窗口

用户在窗口布局上的不同输入元素中输入的数据以字典格式存储。字典键从 0 开始编号,对应于从左到右、从上到下的输入元素。我们可以通过字典运算符引用输入数据。这意味着,第一个元素中的数据由“values[0]”返回。

values = {0: 'kiran', 1: 'Mumbai', 2: '[email protected]'}
data = [values[k] for k in values.keys()]
print (data)

它将在控制台上打印以下内容:

['kiran', 'Mumbai', '[email protected]']

但是,如果您想以编程方式操作元素的值,则必须通过为其 key 参数分配唯一字符串值来初始化该元素。元素的键类似于变量或标识符的名称,这使得以编程方式处理读取或为其赋值变得方便。

key 参数应为字符串。约定是它应该是一个以“-”字符开头和结尾的大写字符串(例如:“- NAME-”)。但是,可以使用任何字符串。

让我们在上面的示例中为输入元素分配键,如下所示:

layout = [
   [psg.Text('Name '),psg.Input(key='-NM-')],
   [psg.Text('Address '), psg.Input(key='-AD-')],
   [psg.Text('Email ID '), psg.Input(key='-ID-')],
   [psg.OK(), psg.Exit()],
]

结果,read() 方法返回的 values 字典将包含键标识符,而不是以前的整数。

OK {'-NM-': 'Kiran', '-AD-': 'Mumbai', '-ID-': '[email protected]'}

现在,values['-NM-'] 将获取“Kiran”。键可以分配给任何元素,而不仅仅是输入元素。您可以使用相同的键来调用元素上的 Update。我们可以使用窗口对象的“find_element(key)”或使用 window['key'] 来引用该元素。

让我们扩展我们之前的示例,在确定和取消按钮之前添加一行,并添加一个带有“-OUT-”键的空文本元素。在 OK 事件中,此文本标签显示在具有键“-NM-”、“-AD-”和“-ID-”的三个输入元素中输入的数据的串联。

import PySimpleGUI as psg
psg.set_options(font=('Arial Bold', 16))
layout = [
   [psg.Text('Name ', size=(15, 1)),
   psg.Input(key='-NM-', expand_x=True)],
   [psg.Text('Address ', size=(15, 1)),
   psg.Input(key='-AD-', expand_x=True)],
   [psg.Text('Email ID ', size=(15, 1)),
   psg.Input(key='-ID-', expand_x=True)],
   [psg.Text('You Entered '), psg.Text(key='-OUT-')],
   [psg.OK(), psg.Exit()],
]
window = psg.Window('Form', layout, size=(715, 200))
while True:
   event, values = window.read()
   print(event, values)
   out = values['-NM-'] + ' ' + values['-AD-'] + ' ' + values['-ID-']
   window['-OUT-'].update(out)
   if event == psg.WIN_CLOSED or event == 'Exit':
      break
window.close()

运行上述代码,在三个输入元素中输入文本,然后按 OK。-OUT- 文本标签将更新如下所示:

Update Window

另一个使用 key 属性的示例如下。为输入元素分配键参数 -FIRST- 和 -SECOND-。有两个按钮,标题分别为 Add 和 Sub。文本元素显示两个数字的加法或减法,具体取决于按下的按钮。

import PySimpleGUI as psg
import PySimpleGUI as psg
psg.set_options(font=('Arial Bold', 16))
layout = [
   [psg.Text('Enter a num: '), psg.Input(key='-FIRST-')],
   [psg.Text('Enter a num: '), psg.Input(key='-SECOND-')],
   [psg.Text('Result : '), psg.Text(key='-OUT-')],
   [psg.Button("Add"), psg.Button("Sub"), psg.Exit()],
]
window = psg.Window('Calculator', layout, size=(715, 180))
while True:
   event, values = window.read()
   print(event, values)
   if event == "Add":
      result = int(values['-FIRST-']) + int(values['-SECOND-'])
   if event == "Sub":
      result = int(values['-FIRST-']) - int(values['-SECOND-'])
   window['-OUT-'].update(result)
   if event == psg.WIN_CLOSED or event == 'Exit':
      break
window.close()

以下屏幕截图显示按下“Add”按钮时的结果。

Updated Window

无边框窗口

默认情况下,应用程序窗口是在客户端区域上方创建了一个标题栏,其中所有其他元素都放置在布局中。标题栏左侧包含窗口标题,右侧包含控制按钮(最小化、恢复/最大化和关闭)。但是,特别是对于类似售货亭的应用程序,不需要标题栏。您可以通过将窗口对象的“no_titlebar”属性设置为“True”来去除标题栏。

Border Window

要终止此类应用程序,必须在发生退出按钮事件时终止事件循环。

禁用关闭的窗口

如果您希望阻止用户最小化应用程序窗口,则应将窗口对象的“disable_minimize”属性设置为 True。类似地,将“disable_close”属性设置为 True,关闭按钮将显示,但不会创建 WINDOW_CLOSED 事件。

Border Disabled

透明窗口

窗口对象的“alpha_channel”属性决定窗口的透明度。其值介于 0 到 1 之间。默认情况下,它为 0,这意味着窗口显示为不透明。将其设置为 1 以使其完全透明。0 到 1 之间的任何浮点值都会使透明度成比例。

Transparent Window

多个窗口

PySimpleGUI 允许同时显示多个窗口。当 PySimpleGUI 模块中的静态函数被调用时,它会读取所有活动窗口。要使窗口处于活动状态,必须将其完成。该函数返回一个 (window, event, values) 结构的元组。

window, event, values = PySimpleGUI.read_all_windows()

如果没有窗口打开,则其返回值为 (None, WIN_CLOSED, None)

在以下代码中,两个函数“win1()”和“win2()”在被调用时分别创建一个窗口。从第一个窗口开始,标题为 Window-2 的按钮会打开另一个窗口,以便两个窗口都处于活动状态。当第一个窗口上发生 CLOSED 事件时,这两个窗口都关闭,程序结束。如果按下第二个窗口上的“X”按钮,则将其标记为已关闭,保留第一个窗口打开。

import PySimpleGUI as psg
def win1():
   layout = [
      [psg.Text('This is the FIRST WINDOW'), psg.Text('', key='-OUTPUT-')],
      [psg.Text('popup one')],
      [psg.Button('Window-2'), psg.Button('Popup'), psg.Button('Exit')]
   ]
   return psg.Window('Window Title', layout, finalize=True)
   def win2():
      layout = [
         [psg.Text('The second window')],
         [psg.Input(key='-IN-', enable_events=True)],
         [psg.Text(size=(25, 1), key='-OUTPUT-')],
         [psg.Button('Erase'), psg.popup('Popup two'), psg.Button('Exit')]]
         return psg.Window('Second Window', layout, finalize=True)
window1 = win1()
window2 = None
while True:
   window, event, values = psg.read_all_windows()
   print(window.Title, event, values)
   if event == psg.WIN_CLOSED or event == 'Exit':
      window.close()
   if window == window2:
      window2 = None
   elif window == window1:
      break
   elif event == 'Popup':
      psg.popup('Hello Popup')
   elif event == 'Window-2' and not window2:
      window2 = win2()
   elif event == '-IN-':
      window['-OUTPUT-'].update('You entered {}'.format(values["-IN-"]))
   elif event == 'Erase':
      window['-OUTPUT-'].update('')
      window['-IN-'].update('')
window.close()

它将生成以下 输出 窗口

Multiple Windows

异步窗口

窗口类的 read() 方法具有以下附加参数:

window.read(timeout = t, timeout_key=TIMEOUT_KEY, close=False)

timeout 参数允许您的 GUI 在非阻塞读取情况下使用。它是您的设备在返回之前可以等待的毫秒数。它创建了一个定期运行的窗口。

您能够添加到超时值的时间越长,您占用的 CPU 时间就越少。在超时时间内,您正在“让出”处理器以执行其他任务。您的 GUI 将比使用非阻塞读取时更具响应性。

timeout_key 参数有助于确定在规定时间内是否有任何用户操作。timeout_key 的默认值为“__timeout__”。

while True:
   event, value = window.read(timeout=10)
   if event == sg.WIN_CLOSED:
      break
   if event == sg.TIMEOUT_KEY:
      print("Nothing happened")

要使窗口可移动,请将窗口对象的“grab_anywhere”属性设置为 true。如果“keep_on_top”属性设置为 True,则窗口将保持在当前窗口之上。

广告