python 笔记 PySimpleGUI 图形界面11-全局设置

整理 PySimpleGUI 官方网站
原文google翻译过来的

https://pysimplegui.readthedocs.io/en/latest/

全局设置

有多种自定义PySimpleGUI的方法。具有最细粒度的呼叫(允许访问特定和精确的设置)。ChangeLookAndFeel实际上,该呼叫是单个呼叫,可SetOptions在其中更改13种不同的设置。

Mac用户 -您无法调用,ChangeLookAndFeel但可以SetOptions使用任何需要的值集进行调用。没有任何东西被阻止或过滤。

这些设置适用于以后创建的所有窗口。

SetOptions。选项和元素选项将优先于这些设置。可以将设置视为设置级别,其中窗口级别为最高,元素级别为最低。因此,级别为:

  • 全球
  • 窗口
  • 元件

每个较低级别将覆盖较高级别的设置。更改设置后,在程序执行期间它们将保持更改状态(除非再次更改)。

永久窗口(单击按钮后窗口保持打开状态)

PySimpleGUI的早期版本没有“持久窗口”的概念。用户单击按钮后,窗口将关闭。一段时间后,功能被扩展,因此默认情况下窗口保持打开状态。

自动清除的输入字段

请注意,执行时可以清除InputTextMultiLine元素。如果要在a 之后清除输入字段,则可以在创建这些元素时将参数设置为False。清除功能逐个元素打开和关闭。read window.read do_not_clear

这背后的原因是持久性Windows通常是“表单”。当“提交”表单时,您希望所有字段都保留为空白,以便下一个数据输入将从一个新窗口开始。另外,在实现“聊天窗口”类型的界面时,每次读取/发送聊天数据后,都希望清除输入字段。将其视为Texting应用程序。如果要发送第二个文本,是否需要清除以前的文本?

基本的永久窗口设计模式

持久Windows的设计模式已经在文档的前面显示给您了……这里是为了您的方便。

import PySimpleGUI as sg

layout = [[sg.Text('Persistent window')],
          [sg.Input()],
          [sg.Button('Read'), sg.Exit()]]

window = sg.Window('Window that stays open', layout)

while True:
    event, values = window.read()
    print(event, values)
    if event in (None, 'Exit'):
        break

window.close()

读(超时= t,timeout_key = TIMEOUT_KEY,close = False)

Read(timeout = t, timeout_key=TIMEOUT_KEY, close=False)

超时读取对于GUI在非阻塞读取情况下使用是一件非常好的事情。如果您的设备可以稍等片刻,请使用这种读取方法。您可以添加到超时值的时间越长,占用的CPU时间就越少。

在返回之前要等待几毫秒的想法。这是使窗口定期运行的简单方法。

超时读取的一种思考方式:

在超时时间内,您正在“屈服”处理器来执行其他任务。

但是它比仅仅成为一个好公民还要好。… 与使用非阻塞读取相比,您的GUI响应更快

假设您有一个要每100毫秒“轮询”的设备。“简单的出路”和直到最近的唯一出路是:

# YOU SHOULD NOT DO THIS您不应该这样做
while True:             # Event Loop
    event, values = window.ReadNonBlocking()   # DO NOT USE THIS CALL ANYMORE
    read_my_hardware() # process my device here
    time.sleep(.1)     # sleep 1/10 second  DO NOT PUT SLEEPS IN YOUR EVENT LOOP!

该程序将快速测试用户输入,然后处理硬件。然后,它将休眠100毫秒,而gui则没有响应,然后它将再次使用GUI进行登录。

使用PySimpleGUI的更好方法…使用读取超时机制,睡眠消失了。

# This is the right way to poll for hardware这是轮询硬件的正确方法
while True:             # Event Loop
    event, values = window.read(timeout = 100)
    read_my_hardware() # process my device here

此事件循环将每100毫秒运行一次。您正在read拨打电话,因此使用该用户所做的任何事情都会立即返回给您,并且您正在等待100毫秒以等待用户执行某项操作。如果用户不执行任何操作,则读取将超时并且执行将返回到程序。

sg.TIMEOUT_KEY

如果您使用具有超时值的读取,则事件值None表示窗口已关闭,就像normal一样window.read。剩下的问题是当没有其他事件发生时将其设置为什么。该值将是的值TIMEOUT_KEY。如果您在读取调用中未指定timeout_key值,那么它将被设置为默认值: TIMEOUT_KEY = __timeout__

如果要在循环中测试“无事件”,则将这样编写:

while True:
    event, value = window.read(timeout=10)
    if event is None:
        break # the use has closed the window
    if event == sg.TIMEOUT_KEY:
        print("Nothing happened")

谨慎使用异步窗口。可能有一个看似异步的窗口,但事实并非如此。 在进入异步窗口之前,请尝试查找其他方法。发出此请求的原因是异步Windows反复轮询tkinter。如果读取中没有超时,并且程序没有其他阻塞,那么您将消耗100%的CPU时间。成为一个好公民很重要。不要不必要地消耗CPU周期。有时您的鼠标想移动您知道吗?

read(timeout=0)

您可能会发现一些PySimpleGUI程序将超时值设置为零。这是非常危险的事情。如果您不喜欢事件循环中的其他内容,那么程序将消耗100%的CPU。请记住,当今的CPU是多核的。在超时为0的情况下运行时,您可能只会看到7%的CPU处于繁忙状态。这是因为任务管理器正在报告系统范围的CPU使用率。您的程序所运行的单核可能是100%。

真正的非阻塞(超时= 0)读取通常保留为“最后手段”。当阻塞读取就可以了,或者读取超时时,人们会使用非阻塞读取的次数太多了。

如果您需要应用程序中每位CPU的强大功能,则将超时值设为零是有效的。也许您的循环正在做一些超级CPU密集型工作,而您的GUI无法使用任何CPU时间。在这种情况下,超时为零是适当的。

成为优秀的计算机公民。以非零超时运行,这样CPU上的其他程序将有时间运行。

小超时值(10ms以下)

不要使用少于10ms的超时时间。否则,您将无所适从,花时间尝试做一些GUI事情,而在完成任何事情之前,都会被超时计时器打扰。结果可能是灾难性的。

有一种混合方法……读取超时。如果您能够通过使用这种类型的读取来节省更多的CPU时间,那么您将在令人印象深刻的仪表上获得更高的分数。

使用非阻塞窗口的最合法时间是直接使用硬件时。也许您正在驾驶串行总线。如果查看Demo_OpenCV_Webcam.py程序中的事件循环,您会看到该读取是非阻塞读取。但是,事件循环中有一个发生阻塞的地方。循环中要阻止的点是从网络摄像头读取帧的调用。当框架可用时,您希望将其快速传送到输出设备,因此您不希望GUI阻塞。您希望阻止从硬件读取。

在演示中可以找到另一个示例,该示例用于控制Raspberry Pi上的机器人。在该应用程序中,您需要阅读方向按钮,前进,后退等,并立即采取措施。如果您使用的是RealtimeButtons,则目前唯一的选择是使用非阻塞窗口。如果要使按钮具有实时响应性,则必须将超时设置为零。

但是,使用这些按钮,在事件循环中添加睡眠至少将使其他进程有时间执行。但是,它将饿死您的GUI。在您整个睡眠期间,您的GUI均未执行。

定期呼叫Read

假设您最终使用了非阻塞读取…那么您需要做一些内务处理。您可以定期“刷新”可见的GUI。在两次GUI更新之间等待的时间越长,窗口的感觉就越迟钝。由您决定是否进行这些调用,否则您的GUI将冻结。

与非阻塞窗口进行交互的方法有2种。1.像读取普通窗口一样读取该窗口。2.在不读取该窗口的情况下“刷新”该窗口的值。这是一项快速操作,旨在向用户显示最新值

使用异步窗口时,会显示该窗口,可以读取用户输入,但是您的代码会不断变化。您的责任是PySimpleGUI.read定期致电。一秒钟几次或更长时间将产生一个相当活泼的GUI。

退出(关闭)永久窗口

如果您的窗口具有关闭该窗口的特殊按钮,则PySimpleGUI将自动为您关闭该窗口。如果您所有的按钮都是普通Button元素,那么完成操作就取决于您要关闭窗口。

要关闭窗口,请调用close方法。

window.close()

从版本4.16.0开始,您可以closewindow.read调用中使用参数来指示应从读取返回之前关闭窗口。这种功能以极好的方式使单行窗口快速获得信息。

这行代码将显示一个窗口,获取用户的输入,关闭该窗口,然后将值作为事件和值字典返回。

event, values = sg.Window('Login Window',
                  [[sg.T('Enter your Login ID'), sg.In(key='-ID-')],
                  [sg.B('OK'), sg.B('Cancel') ]]).read(close=True)

login_id = values['-ID-']

您还可以非常轻松地创建自定义弹出窗口:

long_string = '123456789 '* 40

event, values = sg.Window('This is my customn popup',
                  [[sg.Text(long_string, size=(40,None))],
                  [sg.B('OK'), sg.B('Cancel') ]]).read(close=True)

请注意,None在这种情况下,size的height参数为。对于PySimpleGUI的tkinter端口,这将导致行数“适合”要显示的字符串的内容。

持久窗口示例-运行更新的计时器

有关异步窗口的另一个示例,请参阅GitHub上名为Demo Media Player的示例代码。我们将创建一个窗口,并每0.01秒更新该窗口的元素之一。这是完成此操作的全部代码。

import PySimpleGUI as sg
import time

# ----------------  Create Form  ----------------
sg.ChangeLookAndFeel('Black')
sg.SetOptions(element_padding=(0, 0))

layout = [[sg.Text('')],
         [sg.Text(size=(8, 2), font=('Helvetica', 20), justification='center', key='text')],
         [sg.Button('Pause', key='button', button_color=('white', '#001480')),
          sg.Button('Reset', button_color=('white', '#007339'), key='Reset'),
          sg.Exit(button_color=('white', 'firebrick4'), key='Exit')]]

window = sg.Window('Running Timer', layout, no_titlebar=True, auto_size_buttons=False, keep_on_top=True, grab_anywhere=True)

# ----------------  main loop  ----------------
current_time = 0
paused = False
start_time = int(round(time.time() * 100))
while (True):
    # --------- Read and update window --------
    event, values = window.read(timeout=10)
    current_time = int(round(time.time() * 100)) - start_time
    # --------- Display timer in window --------
    window['text'].update('{:02d}:{:02d}.{:02d}'.format((current_time // 100) // 60,
                                                                  (current_time // 100) % 60,
                                                                  current_time % 100))

以前,该程序是通过在循环中使用睡眠来控制时钟滴答来实现的。此版本使用新的超时参数。结果是一个窗口的反应速度比睡眠状态的窗口要快,而且准确性也很高。

而不是非阻塞读取—使用enable_events = Truereturn_keyboard_events = True

每当您想到“我希望X元素导致Y元素执行某些操作”时,您都想使用该enable_events选项。

代替轮询,尝试使窗口返回给您的选项。 通过使用非阻塞窗口,您可以进行轮询。您确实可以通过轮询来创建应用程序。会的。但是,与使用其他技术相比,您将最大限度地利用处理器,甚至可能需要更长的时间对事件做出反应。

例子

一个示例是您有一个输入字段,当您按屏幕键盘上的按钮时,该输入字段会发生变化。
在这里插入图片描述

更新元素(在活动窗口中更改元素的值)

如果要在创建窗口后在窗口中更改元素的设置,则将调用元素的Update方法。

注意必须先读取或完成一个窗口,然后才能进行任何更新调用。另外,并非所有创建元素时可用的设置都可以通过其update方法使用。

这是更新文本元素的示例

import PySimpleGUI as sg

layout = [ [sg.Text('My layout', key='-TEXT-')],
           [sg.Button('Read')]]

window = sg.Window('My new window', layout)

while True:             # Event Loop
    event, values = window.read()
    if event is None:
        break
    window['-TEXT-'].update('My new text value')

注意Update调用的位置。如果要在事件循环之外的Read调用之前更新Text Element ,则必须首先在窗口上调用Finalize。

在此示例中,更新是在读取之前完成的。因此,将Finalize调用添加到Window创建中。

import PySimpleGUI as sg

layout = [ [sg.Text('My layout', key='-TEXT-')],
           [sg.Button('Read')]]

window = sg.Window('My new window', layout, finalize=True)

window['-TEXT-'].update('My new text value')

while True:             # Event Loop
  event, values = window.read()
    if event is None:
        break

永久窗口保持打开状态,因此在读取返回后继续与用户交互。程序通常希望传达结果(输出信息)或更改元素的值(例如填充列表元素)。

您可以使用Update来执行以下操作:使一个元素(出现)更改为另一个元素禁用按钮,滑块,输入字段等。更改按钮的文本更改元素的文本或背景颜色添加文本到滚动输出窗口更改列表中的选择*等。

完成此操作的方式是通过适用于几乎所有Elements的Update方法。这是使用已更新的持久窗口的程序示例。
在这里插入图片描述

在某些程序中,这些更新是响应另一个元素而发生的。该程序采用微调器和滑块的输入值,并使用它们来调整文本元素的大小。Spinner和Slider在左侧,正在更改的Text元素在右侧。

# Testing async window, see if can have a slider
# that adjusts the size of text displayed

import PySimpleGUI as sg
fontSize = 12
layout = [[sg.Spin([sz for sz in range(6, 172)], font=('Helvetica 20'), initial_value=fontSize, change_submits=True, key='spin'),
           sg.Slider(range=(6,172), orientation='h', size=(10,20),
           change_submits=True, key='slider', font=('Helvetica 20')),
           sg.Text("Aa", size=(2, 1), font="Helvetica "  + str(fontSize), key='text')]]

sz = fontSize
window = sg.Window("Font size selector", layout, grab_anywhere=False)
# Event Loop
while True:
    event, values= window.read()
    if event is None:
        break
    sz_spin = int(values['spin'])
    sz_slider = int(values['slider'])
    sz = sz_spin if sz_spin != fontSize else sz_slider
    if sz != fontSize:
        fontSize = sz
        font = "Helvetica "  + str(fontSize)
        window['text'].update(font=font)
        window['slider'].update(sz)
        window['spin'].update(sz)

print("Done.")

在事件循环内,我们使用那些Elements的键读取Spinner和Slider的值。例如,values['slider']是Slider元素的值。

如果Slider或Spinner更改,则此程序将更改所有3个元素。这是通过以下语句完成的:

window['text'].update(font=font)
window['slider'].update(sz)
window['spin'].update(sz)

请记住此设计模式,因为如果使用持久窗口,则将经常使用它。

它的工作原理如下。此window[key]表达式返回由提供的表示的Element对象key。然后,通过调用其update方法来更新此元素。这是Python的“链接”功能的另一个示例。我们可以使用长格式编写以下代码:

text_element = window['text']
text_element.update(font=font)

此练习的要点是,密钥是PySimpleGUI设计的关键。它们既用于读取窗口的值,也用于标识元素。如前所述,它们已在各种各样的地方使用。

定位元素(FindElement == Element == Elem == [])

用于查找元素的Window方法调用是: FindElement 或缩短的版本 Element 甚至更短的版本(版本4.1+) Elem

现在终于缩短为:window [key]

您会window.Element(key)在旧代码中找到模式。大约4.0之后的所有代码都使用缩短的window[key]符号。

ProgressBar /进度表

请注意,要更改进度条的进度,请致电update_bar,而不要致电update。对于将来的发行版,正在考虑对此进行更改。

  • 5
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值