整理 PySimpleGUI 官方网站
原文google翻译过来的
https://pysimplegui.readthedocs.io/en/latest/
您将找到有关Elements的信息,所有其他类和函数都位于本手册结尾处。它们位于自述文件的大部分中,按字母顺序排列以便于查找。本节对Elements的讨论旨在教您如何工作。另一部分包含详细的呼叫签名和参数定义。
“元素”是用于创建窗口的构建块。一些GUI API使用术语“窗口小部件”来描述这些图形元素。
文本
单线输入
按钮包括以下类型:
文件浏览
选框
单选按钮
列表框
滑杆
多行文字输入/输出
多行文本输出(不适用于tkinter版本)
可滚动输出
立式分离机
进度条
选项菜单
菜单
按钮菜单
帧
柱
图形
图片
表
树
Tab,TabGroup
状态栏
窗格
拉伸(仅Qt)
Sizer(仅适用于PySimpleGUI)
在PySimpleGUI中,键是一个非常重要的概念。
如果要使用GUI进行除基本操作之外的任何操作,则需要了解键。
您可以将“键”视为元素的“名称”。或“标识符”。这是您使用PySimpleGUI库识别和讨论元素的一种方式。它与字典键完全一样。它们对于窗口必须是唯一的。
使用key参数创建元素时指定键。
键通过以下方式使用:在创建元素时指定作为事件返回。如果某个元素导致事件,则将使用其键*在values从中返回的字典中window.read() *为了进行更新(更改),该元素将位于窗口中
将键放入元素的定义后,从中返回的值window.read将使用该键告诉您该值。例如,如果您的布局中有一个输入元素:
Input(key='mykey')
您的阅读如下: event, values = Read()
然后从读取中获取输入值将是: values['mykey']
如果要在元素上调用Update
,则还可以使用相同的键。请参阅“更新元素”部分以了解该用法。为了得到寻找给出的元素的关键元素对象,你可以调用窗口方法find_element
(也写作FindElement,element
),也可以使用更常见的查找机制:
window['key']
虽然在本文档的示例中经常会看到键写为字符串,但要知道键可以是ANYTHING。
假设您有一个带有输入元素网格的窗口。您可以将它们的行和列位置用作键(元组)
key=(row, col)
然后,当您读取values从调用返回的变量时,变量中的Window.read()
键values
将是您用来创建元素的键。在这种情况下,您将读取以下值: values[(row, col)]
大多数情况下,它们是简单的文本字符串。在演示程序中,键是使用以下约定编写的:( _KEY_NAME_在首尾均加大写字母的下划线)或最新的约定是在开头和结尾使用破折号(例如’-KEY_NAME-’)。您不必遵循约定,但是遵循它并不是一个坏习惯,因为其他用户已经习惯了这种格式,并且在使用元素键时很容易发现。
如果有一个元素对象,则要找到其键,请访问.Key该元素的成员变量。假设您已经将元素包含在变量中。
text_elem = sg.Text('', key='-TEXT-')
the_key = text_elem.Key
如果您无法在元素上放置关键点,则会自动为您创建一个关键点。
对于Buttons,按钮上的文本就是该按钮的键。Text元素将默认为文本的字符串(用于启用事件并单击文本时)
如果该元素是输入元素之一(一个会导致在返回值字典中生成条目的元素)而您未指定一个,则将为其分配一个以数字0开头的数字。效果将为即使使用字典也将值表示为列表。
菜单项也可以具有与之关联的键。有关这些特殊键的更多信息,请参见菜单部分。它们与元素键不同。像所有元素一样,菜单元素具有这些元素键之一。各个菜单项的键是不同的。
有时您有一些输入元素(例如Multiline)用作输出。这些元素的内容可能会很长。您无需“读取”这些元素,这样做可能会不必要地返回大量数据。
要告诉PySimpleGUI您不希望元素在Window.read被调用时返回值,请将字符串添加WRITE_ONLY_KEY到键名中。
如果您的Multiline元素最初是这样定义的:
sg.Multiline(size=(40,8), key='-MLINE-')
然后,要关闭该元素的返回值,该Multiline元素将这样编写:
sg.Multiline(size=(40,8), key='-MLINE-' + sg.WRITE_ONLY_KEY)
您几乎可以在所有Element创建调用中看到的一些参数包括:
工具提示是真正修饰GUI并显示出一定水平的那些“抛光”项之一。继续,打动人们,在GUI中添加一些工具提示。您可以通过设置TOOLTIP_BACKGROUND_COLOR为您选择的颜色字符串来更改PySimpleGUI的tkinter版本上工具提示的背景颜色。颜色的默认值为:
TOOLTIP_BACKGROUND_COLOR = “#ffffe0”
尺寸
上面的“窗口”部分讨论了有关设置默认元素大小的信息。
指定为元素保留的空间量。对于基于字符的元素(例如文本),它是(#个字符,#行)。有时它是像素测量,例如Image元素。有时还会像Slider元素(字符长像素宽)上的混合。
某些元素(文本和按钮)具有on默认情况下的自动调整大小设置。它将根据内容确定元素的大小。结果是按钮和文本字段将是创建它们的字符串的大小。您可以关闭它。例如,对于“按钮”,效果是该窗口中所有按钮的大小均相同。
元素大小-非tkinter端口(Qt,WxPython,Web)
在非tkinter端口中,可以通过2种方式设置特定的元素大小。一种是size像以前一样使用常规参数。这将是字符和行。
另一种方法是使用新参数size_px。此参数允许您直接以像素为单位指定大小。设置为size_px=(300,200)将会创建300 x 200像素的元素。
此外,如果尺寸超过转换阈值size,则还可以使用参数指示像素。 这意味着什么?这意味着如果您的宽度> 20(DEFAULT_PIXEL_TO_CHARS_CUTOFF),则假定您是在说像素,而不是字符。但是,某些“通常较大”的元素的截断值为100。例如,这些元素包括Multline和Output元素。
如果您对用于进行字符到像素转换的数学方法感到好奇,那么它是很粗糙的,但是功能丰富。借助以下变量完成转换:
DEFAULT_PIXELS_TO_CHARS_SCALING = (10,26)
转换只是将您的size[0]乘以10,然后将您的size[1]乘以26。
色彩
代表颜色的字符串。只要涉及到颜色,就可以指定tkinter颜色名称,例如’lightblue’或RGB十六进制值’#RRGGBB’。对于按钮,color参数是一个元组(文本颜色,背景颜色)
任何时候在PySimpleGUI中将颜色写为元组时,找出哪种颜色是背景的方法就是用单词“ on”替换“,”。(“白色”,“红色”)指定一个按钮,该按钮为“红色上的白色”。适用于有颜色元组的任何地方。
垫
元素周围的空间量(以像素为单位)。默认值为(5,3),这意味着在x轴的每一侧保留5个像素,在y轴的每一侧保留3个像素。您可以使用SetOptions调用在全局基础上或在元素基础上进行更改。
如果您希望一侧上的像素多于另一侧,则可以将数字分成2个数字。如果要在左侧200像素,在右侧3像素,则填充为((200,3),3)。在此示例中,仅x轴被拆分。
字形
指定字体系列,大小和样式。Windows上的字体家族包括:* Arial * Courier 漫画, Fixedsys * Times * Verdana * Helvetica(我认为是默认设置)
字体因系统而异,但是,Tk 8.0会在所有平台上自动将Courier,Helvetica和Times映射到其对应的本机姓氏。同样,字体家族不能导致Tk 8.0及更高版本上的字体规范失败。
如果您希望将字体系列保留为默认设置,则可以将非字体名称的任何内容作为字体。PySimpleGUI演示程序和文档使用家族“ Any”来证明这一事实。如果您更清楚地知道,则可以使用“默认”。
有2种格式可用于指定字体…字符串和元组Tuple-(系列,大小,样式)字符串-“ Family Size Styles”
若要指定带下划线的Helvetica字体,其值的大小为15 :(“ Helvetica”,15,“ underline italics”),“ Helvetica 15 underline italics”
键
请参阅上面有关键的完整信息的部分。
可见
从版本3.17开始,您可以创建最初不可见的元素,以后可以使它们可见。
要创建不可见的元素,请像平常一样将元素放置在布局中并添加参数
visible=False。
稍后,当您希望使该Element可见时,您只需调用Element的Update方法并传递参数visible=True
此功能在Qt上效果最好,但在tkinter版本上也适用。visible参数也可以与Column and Frame“容器”元素一起使用。
注意-当从不可见变为可见时,Tkinter元素的行为与Qt元素不同。
tkinter元素倾向于自己堆叠。
一种解决方法是将元素放置在“列”中,并在其行上放置其他元素。这将保留要放置的行的位置。但是它将把元素移到该行的末尾。
如果不仅要使元素不可见,还可以在tkinter上调用`Element。
Qt元素倾向于很好地保持其位置,并且窗口可以很好地调整自身大小。它更加精确,并且不笨重。
也许这不是最好的主意,但是方法和函数的命名仍然是一个不错的选择。一些“重载元素”(以及方法/功能)中的某些具有“快捷方式”。
换句话说,我很懒,不喜欢打字。结果是有多种方法可以做完全相同的事情。通常,演示程序和其他示例使用全名,或至少使用更长的名称。幸运的是,无论您使用哪种格式,PyCharm都会向您显示相同的文档。
习惯了使用SDK后,这使您可以更快地进行编码。例如,文本元素具有3个不同的名称Text,Txt即T。InputText也可以编写为Input或In。
快捷方式不仅限于Elements。该Window方法Window.FindElement可以这样写,Window.Element因为它是这样一种常用函数。但是,即使现在已经缩短为window[key]
这是一个持续的事情。如果您不了解最新信息,而是使用了较新的快捷方式之一,则只需在代码中重命名该快捷方式即可。例如,如果您的版本中没有sg.T,请用sg.Text替换sg.T。
基本元素。它显示文本。
layout = [
[sg.Text('This is what a Text Element looks like')],
]
创建稍后要更新的文本元素时,请确保为新文本保留足够的字符。创建不带size参数的文本元素时,它会完全适合提供的字符。
使用比例间隔字体(通常是默认设置),即使一组字符数相同,一组字符的像素大小也会与另一组字符的像素大小不同。换句话说,并非所有字母都使用相同数量的像素。看看您现在正在阅读的文字,您会看到。“ i”占用的空间少于“ A”占用的空间。
在使PySimpleGUI代码更紧凑方面实现了巨大的飞跃。
而不是写:
window.FindElement(key).update(new_value)
您现在可以将其编写为:
window[key].update(new_value)
此更改已发布到PyPI for PySimpleGUI
非常感谢nngogol的建议,并向我展示了如何执行此操作。 与他的许多建议一样,这是一个令人难以置信的发现。
##Element.update()
->Element()
快捷方式
这一定是我写过的最奇怪的句法构造之一。
最好与FindElement
结合使用(请参见前面的有关如何快捷化FindElement
的部分)。
通常,要更改元素,您可以“查找”该元素,然后调用其“ update”方法。 如上一节中所见,代码通常看起来像这样:
window[key].update(new_value)
可以通过删除.update字符来进一步压缩代码,从而产生一个非常紧凑的外观:
window[key](new_value)
是的,这是Python中的有效语句。
发生的是该元素本身正在被调用。您也可以这样编写:
elem = sg.Text('Some text', key='-TEXT-')
elem('new text value')
旁注-您也可以window直接调用变量。如果您“呼叫”它实际上会呼叫
Window.read。
window = sg.Window(....)
event, values = window()
# 是相同的
window = sg.Window(....)
event, values = window.read()
但是看起来很混乱,所以在使用时最好在语句末尾写一个注释,以帮助那些可怜的初学者程序员。
因为这是一个非常陌生的构造,所以使用1周Python类的人将无法识别,因此演示将继续使用该.update方法。
它不必与结合使用FindElement。该调用适用于任何先前创建的元素。有时会创建元素,将其存储到变量中,然后在布局中使用该变量。例如。
graph_element = sg.Graph(...... lots of parms ......)
layout = [[graph_element]]
.
.
.
graph_element(background_color='blue') #这为先前定义的元素调用Graph.update
希望这不会太令人困惑。请注意,这些快捷方式替换的方法不会被删除。您可以继续使用旧结构而无需进行任何更改。
字型
已经在通用参数部分讨论过。字符串或元组。
可以使用tkinter中定义的颜色名称或这种格式的RGB字符串指定各个颜色:
"#RRGGBB" or "darkblue"
当True值auto_size_text放置在“文本元素”上时,表示该元素的宽度应缩小为文本的宽度。默认设置为True。创建Text用于输出的元素时,需要记住这一点。
Text(key=’-TXTOUT-)将创建一个Text长度为0 的元素。注意,对于具有空字符串的Text元素,不需要指示任何字符串值。字符串的默认值为’'文本元素。如果您尝试输出5个字符的字符串,则由于空间不足,该字符串将不会显示在窗口中。补救措施是将大小手动设置为您希望输出的大小
Text(size=(15,1), key='-TXTOUT-)
创建一个Text可以容纳15个字符的元素。
的简写功能Text是Txt和T
如果您设置了参数,enable_events那么如果用户单击“文本”,则会收到一个事件。
此元素同时用作输入和输出元素。
layout = [[sg.Multiline('This is what a Multi-line Text Element looks like', size=(45,5))]]
随着时间的推移,此元素已经扩展了很多。其中两个更令人兴奋的新增功能是
能够按字符输出唯一的文本和背景颜色
update。这些查询之一通常会出现:
window['-MULTILINE KEY-']
要更改您的常规打印内容之一以输出到多行元素,只需在打印语句的前面添加上述查找表达式即可。
print('My variables are', a, b, c) # a normal print statement
window['-MULTILINE KEY-'].print('My variables are', a, b, c)
# Routed to your multiline element路由到多行元素
不过它会变得更好。…您可以在打印件中添加颜色
# 在黄色背景上输出红色文本
window['-MULTILINE KEY-'].print('My variables are', a, b, c, text_color='red', background_color='yellow')
使用此打印功能的另一种方法是重新定义print语句本身。这将允许您完全保留您的代码。通过添加此行代码,您的整个程序会将所有打印的信息输出到多行元素。
print = lambda *args, **kwargs: window['-MULTILINE KEY-'].print(*args, **kwargs)
layout = [[sg.InputText('Default text')]]
关于do_not_clear参数的注意事项
这曾经使人们绊倒,但现在不这么认为了。在do_not_clear创建的inputText元素时参数进行初始化。如果设置为False,则每次Window.read()调用后都会删除输入字段的内容。当您的窗口是“输入表单”类型的窗口时,您要擦除所有字段并每次重新开始时,请使用此设置。
也称为下拉列表。仅必需的参数是选项列表。返回值是一个与GUI上可见的字符串匹配的字符串。
layout = [[sg.Combo(['choice 1', 'choice 2'])]]
在大多数GUI中都可以找到类似的标准列表框。请注意,此元素的返回值将是结果列表,而不是单个result。这是因为用户可以从列表中选择多个项目(如果您设置了正确的模式)。
layout = [[sg.Listbox(values=['Listbox 1', 'Listbox 2', 'Listbox 3'], size=(30, 6))]]
列表框可能导致窗口从Read调用返回。如果enable_events设置了该标志,则当用户进行选择时,读取立即返回。
ListBoxes可以导致Reads返回的另一种方法是是否设置了标志bind_return_key。如果为True,则在选择条目时用户按下返回键,则Read返回。同样,如果设置了此标志,则如果用户双击一个条目,它将从读取中返回。
滑块具有几个特定于滑块的设置以及外观设置。示例包括orientation和range设置。
layout = [[sg.Slider(range=(1,500),
default_value=222,
size=(20,15),
orientation='horizontal',
font=('Helvetica', 12))]]
Qt滑杆
Qt和tkinter滑块之间存在重要区别。在Qt上,滑块值必须是整数,而不是浮点数。如果您希望滑块从0.1变为1.0,则使滑块从1变为10并除以10。这是一件容易的数学事情,没什么大不了的。只是处理它。。。您毕竟是在编写软件。大概您知道如何做这些事情。
创建一个分配给一组单选按钮的单选按钮。一次只能选择该组中的一个按钮。
layout = [
[sg.Radio('My first Radio!', "RADIO1", default=True),
sg.Radio('My second radio!', "RADIO1")]
]
复选框元素类似于单选按钮元素。它们返回一个布尔值,指示是否已对其进行检查。
layout = [[sg.Checkbox('My first Checkbox!', default=True), sg.Checkbox('My second Checkbox!')]]
向上/向下微调器控件。有效值将作为列表传递。
layout = [[sg.Spin([i for i in range(1,11)], initial_value=1), sg.Text('Volume level')]]
图像可以以PNG,GIF,PPM / PGM格式放置在窗口中。无法显示JPG,因为tkinter并不天真支持JPG。如果图像为JPG格式,则可以在调用PySimpleGUI之前使用Python Imaging Library(PIL)包将图像转换为PNG。
layout = [
[sg.Image(r'C:\PySimpleGUI\Logos\PySimpleGUI_Logo_320.png')],
]
您可以将动画GIF指定为图像,并可以通过调用来设置GIF动画UpdateAnimation。令人兴奋的东西!
您可以在不设置time_between_frames值的情况下调用该方法,该方法将显示一个框架并立即移至下一框架。这使您可以进行帧间计时。
按钮是最重要的元素!它们导致大多数动作发生。毕竟,这是一个按下按钮的操作,它将使您跳出一个窗口,无论是“提交”还是“取消”,所有窗口中都涉及一种按钮。唯一的例外是,当用户使用上角的“ X”关闭窗口时,这意味着不涉及任何按钮。
按钮的类型包括:文件夹浏览文件浏览文件浏览文件另存为文件保存关闭窗口(正常按钮)读取窗口实时日历选择器颜色选择器
关闭窗口-常规按钮,例如“提交”,“取消”,“是”,“否”,不要关闭窗口…它们曾经使用过。现在要关闭窗口,您需要使用CloseButton / CButton。
文件夹浏览-单击后,将打开一个文件夹浏览对话框。文件夹浏览对话框的结果将写入窗口的输入字段之一。
文件浏览-与文件夹浏览相同,只是选择一个文件而不是选择一个文件夹。
日历选择器-打开图形日历以选择日期。
颜色选择器-打开颜色选择器对话框
读取窗口-这是一个窗口按钮,将读取所有输入字段的快照,但是在单击窗口后不会关闭该窗口。
实时-这是另一个异步窗口按钮。释放按钮的单击后,将发生正常的按钮单击。实时按钮报告在按下按钮的整个过程中单击。
大多数程序将组合使用快捷方式按钮调用(提交,取消等),使窗口保持打开状态的普通按钮和单击时关闭窗口的关闭按钮。
有时,同一功能有多个名称。这仅仅是为了使程序员的工作更快,更轻松。或者,它们是不再使用但保留的旧名称,以使现有程序不会中断。
PySimpleGUI按钮的4个主要窗口及其名称为:
您会在较旧的程序中找到长格式名称。以ReadButton为例。
在2018年10月,Button的定义发生了变化。以前,Button在单击时将关闭窗口。它已被更改,因此Button调用将以与ReadButton完全相同的方式使窗口保持打开状态。他们现在是相同的电话。为了使窗口可以使用按钮关闭,添加了一个新按钮… CloseButton或CButton。
您的PySimpleGUI程序很可能仅包含Button调用。其他代码通常在用户代码中找不到。
使用的最基本的Button元素调用是 Button
layout = [[sg.Button('Ok'), sg.Button('Cancel')]]
您很少会特别看到以这种方式编写的这两个按钮。回想一下,PySimpleGUI专注于您(通常直接意味着……减少打字)。因此,通常使用下一部分中找到的快捷方式编写上述窗口的代码。
您通常会看到此内容,而不是致电Button:
layout = [[sg.Ok(), sg.Cancel()]]
在现实中Button其实是在被称为以您的名义。在后台,sg.Ok并sg.Cancel呼吁Button与文本设置为Ok和Cancel和返回的结果则进入布局。如果要打印布局,它将看起来与在布局Button中专门显示的第一个布局相同。
在2019年增加了对ttk Buttons的支持。这可以解决无法在Mac上更改按钮颜色的问题。在MAc或其他平台上,可以在很多地方控制是否使用ttk按钮。
TTK按钮和TK按钮的操作略有不同。按钮突出显示是一种不同。如何同时显示图像和文本是另一个。您现在拥有以前没有的选项。很高兴看到Mac用户终于可以使用颜色主题了。
这些预制按钮是所有按钮中最重要的元素,因为它们已被大量使用。它们基本上都做相同的事情,设置按钮文本以匹配功能名称,并将参数设置为常用值。如果您发现自己经常需要创建自定义按钮,因为该按钮不在此列表中,请在GitHub上发布请求。它们包括:
这些按钮用于显示对话框,这些对话框选择文件名,日期,颜色等填充到InputText元素(或其他“目标”……中的目标)。
关于快捷按钮的重要说明 在3.11.0发行版之前,这些按钮关闭了窗口。从3.11开始,它们将不会关闭窗口。它们的行为类似于RButton(返回按钮文本并且不关闭窗口)
如果您在关闭窗口时无法使用这些按钮,请pip list在命令提示符下键入以检查已安装的PySimpleGUI版本。在3.11之前,这些按钮会关闭您的窗口。
使用较旧的版本,如果您希望不关闭窗口的Submit()按钮,则应使用RButton(‘Submit’)。使用新版本时,如果您希望像一个已售出的Submit()调用那样关闭窗口的Submit按钮,可以将其写为CloseButton(‘Submit’)or。CButton(‘Submit’)
的FileBrowse,FolderBrowse,FileSaveAs,FilesSaveAs,CalendarButton,ColorChooserButton按钮所有填充值到位于窗口上的另一个元件。目标可以是Text元素或InputText元素或按钮本身。元素的位置由target函数调用中的变量指定。
目标有两种形式。1.键2.(行,列)
使用键指定的目标将通过使用目标的键值找到其目标元素。这是“首选”方法。
如果使用(行,列)指定了目标,则它将利用网格系统。GUI中的行从0开始编号。目标可以指定为硬编码网格项,也可以相对于按钮指定。
(行,列)定位只能定位相同“容器”中的元素。容器是窗口,列和框架元素。列内的“文件浏览”按钮无法定位该列外的元素。
其缺省值target是(ThisRow, -1)。 ThisRow是一个特殊值,它告诉GUI使用与按钮相同的行。Y值-1表示按钮左侧的字段一。对于“文件或文件夹浏览”按钮,大多数情况下,其填充的字段通常位于按钮的左侧。(ThisRow,-1)表示同一行上按钮左侧的Element。
如果(None, None)为目标选择了值,则按钮本身将保存信息。之后,可以使用按钮的键查询按钮的值。
让我们以这个窗口为例:
该InputText元件位于(1,0)…行1,列0的Browse按钮位于位置(2,0)。该按钮的目标可以是以下任何值:
Target = (1,0)
Target = (-1,0)
整个窗口的代码可能是:
layout = [[sg.T('Source Folder')],
[sg.In()],
[sg.FolderBrowse(target=(-1, 0)), sg.OK()]]
或者,如果使用键,则代码为:
layout = [[sg.T('Source Folder')],
[sg.In(key='input')],
[sg.FolderBrowse(target='input'), sg.OK()]]
看看关键方法要容易得多吗?
一种非常方便的技巧是使目标不可见。这将消除编辑输入值的能力,就像通常使用输入元素一样。这是使事情看起来更整洁,也许也不太混乱的一种方式。
有4种不同类型的“文件/文件夹打开”对话框。如果您正在寻找要打开的文件,则FileBrowse是您想要的。如果要保存文件,SaveAs请单击按钮。如果要获取文件夹名称,则FolderBrowse是要使用的按钮。要一次打开多个文件,请使用FilesBrowse按钮。它将创建一个用“;”分隔的文件列表。
这些按钮会弹出一个标准的颜色选择器窗口。结果以元组形式返回。返回的值之一是RGB十六进制表示形式。
自定义按钮
并非所有按钮均创建相同。关闭窗口的按钮与从窗口返回而不关闭窗口的按钮不同。如果要定义自己的按钮,通常将使用Button元素来执行此操作,Button单击该按钮时会关闭窗口。
layout = [[sg.Button('My Button')]]
通过更改button_text按钮调用中的参数,可以更改所有按钮的文本。读取窗口时将返回此文本。该文本将告诉您单击了哪个按钮。但是,您也可以在按钮上使用键,这样它们将是唯一的。如果仅使用文本,则您将永远无法在同一窗口中使用相同文本的两个按钮。
layout = [[sg.Button('My Button', key='_BUTTON_KEY_')]]
在这种布局下,Window.read()单击按钮后从呼叫返回的事件将是“ BUTTON_KEY”
现在,这是许多简化软件包中都没有的令人兴奋的功能。…按钮上的图像!您可以借助一些按钮图像来制作漂亮的用户界面。
这是将tkinter从“ 1990年代外观GUI”转换为“现代GUI”的最快,最简单的方法之一。如果您不喜欢默认按钮,则只需带上自己的按钮图像,然后使用它们即可。
您的按钮图片必须为PNG或GIF格式。用图像制作按钮时,请将按钮背景设置为与背景相同的颜色。您可以通过调用获取主题的背景色theme_background_color()
TRANSPARENT_BUTTON- 重要 -这是一个具有误导性的传统价值。当前定义为以下常量值:
TRANSPARENT_BUTTON = ('#F0F0F0', '#F0F0F0')
如您所见,它只是2种灰色的元组。效果是按钮文本和按钮背景色变为特定的灰色阴影。时光倒流,在您可以更改背景颜色和所有窗口均为灰色之前,此值有效。但是,既然您的按钮可以使用任何背景色,那么您将需要设置按钮的颜色以使其与背景匹配,以使您的按钮与背景色融合。
sg.Button('Restart Song', button_color=(sg.theme_background_color(), sg.theme_background_color()),
image_filename=image_restart, image_size=(50, 50), image_subsample=2, border_width=0)
Button元素中有几个用于按钮图像的参数。
image_filename - Filename of image. Can be a relative path
图像的文件名。可以是相对路径
image_data - A Base64 image
Base64图像
image_size - Size of image in pixels
图像大小(像素)
image_subsample - Amount to divide the size by. 2 means your image will be 1/2 the size. 3 means 1/3
等于除以大小。2表示您的图像将是1/2大小。3表示1/3
这是一个使用按钮图像制作的示例窗口。
您将在Demo Media Player文件中找到源代码。这是创建媒体播放器窗口时按钮调用的外观
python sg.Button('Pause',button_color =(sg.theme_background_color(),sg.theme_background_color()),image_filename = image_pause,image_size =(50,50),image_subsample = 2,border_width = 0)
有时需要进行实验才能使这些概念真正生效,并且它们可能会根据基础GUI框架而有所不同。
按钮图像确实起作用,因此请与它们一起玩。 您可以使用PIL更改图像的大小,然后再传递给PySimpleGUI。
###实时按钮
通常,在向下单击按钮后放开鼠标按钮时,按钮被视为“已单击”。 何时需要读取原始的上/下按钮值呢? 一个典型的例子是机器人遥控器。 使用GUI构建遥控器非常容易。 每个方向的一个按钮是一个开始。 也许是这样的:
![机器人远程](https://user-images.githubusercontent.com/13696193/44959958-ff9b7000-aec4-11e8-99ea-7450926409be.jpg)
该窗口有2种按钮类型。 有正常的“读取按钮”(退出)和4个“实时按钮”。
这是从此窗口制作,显示和获取结果的代码
import PySimpleGUI as sg
gui_rows = [[sg.Text('Robotics Remote Control')],
[sg.T(' ' * 10), sg.RealtimeButton('Forward')],
[sg.RealtimeButton('Left'), sg.T(' ' * 15), sg.RealtimeButton('Right')],
[sg.T(' ' * 10), sg.RealtimeButton('Reverse')],
[sg.T('')],
[sg.Quit(button_color=('black', 'orange'))]
]
window = sg.Window('Robotics Remote Control', gui_rows)
#
# Some place later in your code...在你的代码后面的某个地方。。。
# You need to perform a Read or Refresh call on your window every now and then or您需要不时地对窗口执行读取或刷新调用,或者
# else it will apprear as if the program has locked up.
#否则它会像程序被锁定一样通知。
# your program's main loop你程序的主循环
while (True):
# This is the code that reads and updates your window
event, values = window.read(timeout=50)
print(event)
if event in ('Quit', None):
break
window.close() # Don't forget to close your window!
此循环将读取按钮值并进行打印。单击“实时”按钮之一时,对的调用window.read将返回与按下的按钮上的名称匹配的按钮名称,或者返回已分配给该按钮的按键的名称。只要按钮保持按下状态,它将继续返回值。释放后,读取将返回超时事件,直到再次单击按钮。
文件类型 的FileBrowse和SaveAs按钮有一个名为额外的设置file_types。此变量用于过滤文件对话框中显示的文件。此设置的默认值为
FileTypes=(("ALL Files", "*.*"),)
这段代码产生一个窗口,其中“浏览”按钮仅显示.TXT类型的文件
layout = [[sg.In() ,sg.FileBrowse(file_types=(("Text Files", "*.txt"),))]]
注意-Mac用户将无法使用file_types参数。tkinter在Mac上存在一个错误,如果尝试使用file_type,则该错误将使程序崩溃,因此必须删除此功能。对于那个很抱歉!
ENTER键 ENTER键是Windows数据输入的重要部分。长期以来,使用Enter键来快速提交窗口。PySimpleGUI通过将ENTER键绑定到关闭或读取窗口的第一个按钮来实现此目的。
可以将Enter键“绑定”到特定按钮,以便在按下该键时,它会使窗口返回,就像单击该按钮一样。这是使用bind_return_key按钮调用中的参数完成的。如果窗口上有多个按钮,则使用“关闭”窗口或“读取”窗口类型的“第一”按钮。首先通过从上至下,从左至右扫描窗口来确定。
ButtonMenu元素产生独特的效果。这是一个按钮,单击后会显示一个菜单。这就像单击MenuBar上的顶级菜单项之一。结果,菜单定义采用普通菜单定义中单个菜单项的格式。正常的菜单定义是列表列表。该定义是这些列表之一。
['Menu', ['&Pause Graph', 'Menu item::optional_key']]
通常,第一个字符串指定菜单栏上显示的内容。在这种情况下,不使用该值。您可以使用另一个参数button_textparm 来设置按钮的文本。
此元素的一种用法是制作一个带有彩色背景的“假菜单栏”。普通菜单栏不能更改其背景颜色。ButtonMenus并非如此。
ButtonMenus的返回值通过返回值字典发送。如果做出选择,则将生成一个事件,该事件将等于ButtonMenu的键值。使用该键值来查找用户选择的值。这与菜单栏元素的机制相同,但与弹出菜单(单击鼠标右键)不同。
此元素的用途有限,为完整性起见,比其他任何元素都包含更多。它将在元素之间画一条线。
当放置在跨越多行的列或元素之间时,效果最佳。如果在“普通”行上且元素只有1行高,则它将仅跨越该行。
VerticalSeparator(pad=None)
在Tyinter端口PySimpleGUI中,没有HorizontalSeparatorElement。一个将被添加为“存根”,以便代码可移植。它可能不会像StretchElement 一样无所作为。
在PySimpleGUI中获得水平线的一种简单方法是使用Text包含下划线的Element
sg.Text('_'*30)
# make a horizontal line stretching 30 characters
#画一条横线,长30个字符
该ProgressBar元素用于构建自定义进度栏窗口。强烈建议您使用OneLineProgressMeter,它为您提供完整的进度表解决方案。进度表不容易使用,因为窗口必须是非阻塞的,并且调试起来很棘手。
将进度表纳入代码的最简单方法是使用OneLineProgressMeterAPI。这由一对函数OneLineProgressMeter和组成OneLineProgressMeterCancel。您可以通过使用当前值=最大值调用进度表来轻松取消它。这将把仪表标记为过期并关闭窗口。您已经在本自述文件的前面看到了OneLineProgressMeter调用。
sg.OneLineProgressMeter('My Meter', i+1, 1000, 'key', 'Optional message')
返回值OneLineProgressMeter是: True如果False用户单击“取消”按钮,关闭窗口或阀门达到最大值,则仪表正确更新 。
窗口中的进度表
将进度表与PySimpleGUI一起使用的另一种方法是使用窗口中的ProgressBarElement 来构建自定义窗口。您需要将您的窗口作为非阻塞窗口运行。准备好更新进度条时,可以调用元素本身的UpdateBar方法ProgressBar。
import PySimpleGUI as sg
# layout the window
layout = [[sg.Text('A custom progress meter')],
[sg.ProgressBar(1000, orientation='h', size=(20, 20), key='progressbar')],
[sg.Cancel()]]
# create the window`
window = sg.Window('Custom Progress Meter', layout)
progress_bar = window['progressbar']
# loop that would normally do something useful
for i in range(1000):
# check to see if the cancel button was clicked and exit loop if clicked
event, values = window.read(timeout=10)
if event == 'Cancel' or event is None:
break
# update bar with loop value +1 so that bar eventually reaches the maximum
progress_bar.UpdateBar(i + 1)
# done with loop... need to destroy the window as it's still open
window.close()
输出元素是Stdout的重定向。
如果您正在寻找一种快速添加在窗口内显示滚动文本的功能的方法,那么添加Output元素就变得一样快捷和容易。
任何“已打印”的内容都将显示在此元素中。 这是在窗口中显示滚动文本的“简单”方法。就像将Output Element放到窗口中,然后根据需要调用print一样简单。用户将在其窗口内看到文本的滚动区域。
重要事项 您print必须先致电window.read或,才能看到自己的名字window.Refresh。如果要立即查看打印的内容,请window.Refresh()在打印语句后立即致电。
Output(size=(80,20))
这是使用Output元素的聊天窗口的完整解决方案。要显示接收到的数据,您只需简单地“打印”它,它就会显示在输出区域中。您会在包括HowDoI应用程序在内的多个演示程序中找到使用此技术的方法。
import PySimpleGUI as sg
def ChatBot():
layout = [[(sg.Text('This is where standard out is being routed', size=[40, 1]))],
[sg.Output(size=(80, 20))],
[sg.Multiline(size=(70, 5), enter_submits=True),
sg.Button('SEND', button_color=(sg.YELLOWS[0], sg.BLUES[0])),
sg.Button('EXIT', button_color=(sg.YELLOWS[0], sg.GREENS[0]))]]
window = sg.Window('Chat Window', layout, default_element_size=(30, 2))
# ---===--- Loop taking in user input and using it to query HowDoI web oracle --- #
while True:
event, value = window.read()
if event == 'SEND':
print(value)
else:
break
window.close()
ChatBot()
列,框架和选项卡都是“容器元素”,并且行为类似。本节重点介绍“列”,但可以在其他地方应用。
从2.9版开始,您将可以使用Column Element进行更复杂的布局。将列视为窗口中的一个窗口。而且,是的,如果需要,您可以在列中有一个列。
像所有“容器元素”一样,以与窗口完全相同的方式将列指定为列表列表。
当您要在一行中指定多个元素时,需要使用列。
例如,此布局具有单个滑块元素,该元素跨越几行,后跟7 Text和Input同一行上的元素。
没有列元素,就无法创建这样的布局。但是有了它,您应该能够仅使用tkinter紧密匹配任何布局。
import PySimpleGUI as sg
# Demo of how columns work
# window has on row 1 a vertical slider followed by a COLUMN with 7 rows
# Prior to the Column element, this layout was not possible
# Columns layouts look identical to window layouts, they are a list of lists of elements.
window = sg.Window('Columns') # blank window
# Column layout
col = [[sg.Text('col Row 1')],
[sg.Text('col Row 2'), sg.Input('col input 1')],
[sg.Text('col Row 3'), sg.Input('col input 2')],
[sg.Text('col Row 4'), sg.Input('col input 3')],
[sg.Text('col Row 5'), sg.Input('col input 4')],
[sg.Text('col Row 6'), sg.Input('col input 5')],
[sg.Text('col Row 7'), sg.Input('col input 6')]]
layout = [[sg.Slider(range=(1,100), default_value=10, orientation='v', size=(8,20)), sg.Column(col)],
[sg.In('Last input')],
[sg.OK()]]
# Display the window and get values
window = sg.Window('Compact 1-line window with column', layout)
event, values = window.read()
window.close()
sg.Popup(event, values, line_width=200)
从版本4.3开始,您可以设置任何容器元素的对正。这是通过element_justification参数完成的。这将极大地帮助希望将其所有内容居中放在窗口中的任何人。以前,即使不是不可能,也很难进行这类布局。
Column通过设置Column的justification参数来对齐元素的行。
您还可以Column通过使用Column的element_justification参数来证明其中的全部内容。
使用这些参数,可以创建内容居中的窗口。以前这很难做到。
当前仅在主要的PySimpleGUI端口中可用。
它们也可以用于以特定方式证明一组元素的合理性。
将Column元素放置在元素内部Columns可以创建大量的
SizerElement 是4.3中的新功能。此元素用于帮助创建特定大小的容器。可以将其放置在以下PySimpleGUI项目中:
a的实现Sizer非常简单。它返回一个空Column元素,其填充值设置为传递给的值Sizer。因此,它不是一个类,而是一个类似于预定义按钮的“快捷功能”。
目前,此功能仅在PySimpleGUI的tkinter端口中可用。需要一个交叉端口。
框架的工作方式与“列”完全相同。您创建布局,然后用于初始化框架。就像Column元素一样,它是一个“容器元素”,其中包含一个或多个元素。
注意“框架”布局看起来与窗口布局完全相同。窗口的工作方式与“列”和“框架”完全相同。它们都是“容器元素”-包含其他元素的元素。
这些容器元素可以嵌套到所需的深度。这是一个非常漂亮的功能,对吗?做了大量的工作,所以要感谢。递归代码并非易事。
此代码创建一个带有Frame和2个按钮的窗口。
frame_layout = [
[sg.T('Text inside of a frame')],
[sg.CB('Check 1'), sg.CB('Check 2')],
]
layout = [
[sg.Frame('My Frame Title', frame_layout, font='Any 12', title_color='blue')],
[sg.Submit(), sg.Cancel()]
]
window = sg.Window('Frame with buttons', layout, font=("Helvetica", 12))
我认为,tkinter画布小部件是tkinter小部件中功能最强大的。尽管我尽最大努力将用户与与tkinter相关的任何事物完全隔离开来,但Canvas元素是一个例外。它可以与许多其他程序包集成,通常会产生出色的结果。
但是,还有另一种获得此功能的方法,那就是通过Graph元素,它甚至是功能更强大的元素,因为它使用了Canvas,您可以在需要时直接访问它。Graph元素具有许多Canvas元素不具备的绘制方法。另外,如果需要,您可以通过成员变量访问图形元素的“画布”。
注意-最新版本的Matplotlib(3.1.0)不再适用于该技术。您必须安装3.0.3才能使用“演示程序”部分中提供的演示Matplotlib程序。
Matplotlib和Pyplot就是这样一种集成。有一个编写的演示程序,您可以将其用作设计模式,以了解在使用Canvas Widget后如何使用它。
def Canvas(canvas - a tkinter canvasf if you created one. Normally not set
background_color - canvas color
size - size in pixels
pad - element padding for packing
key - key used to lookup element
tooltip - tooltip text)
获取tkinter画布小部件的操作顺序为:
figure_x, figure_y, figure_w, figure_h = fig.bbox.bounds
# define the window layout
layout = [[sg.Text('Plot test')],
[sg.Canvas(size=(figure_w, figure_h), key='canvas')],
[sg.OK(pad=((figure_w / 2, 0), 3), size=(4, 2))]]
# create the window and show it without the plot
window = sg.Window('Demo Application - Embedding Matplotlib In PySimpleGUI', layout).Finalize()
# add the plot to the window
fig_photo = draw_figure(window['canvas'].TKCanvas, fig)
# show it all again and get buttons
event, values = window.read()
要从PySimpleGUI获取tkinter画布小部件,请按照以下步骤操作:将Canvas元素添加到窗口中布局窗口调用window.Finalize()-这是您不能忘记的关键步骤通过使用键查找来查找Canvas元素*您的Canvas小部件对象将是found_element.TKCanvas 在画布上绘制到您内心的内容调用window.read()-在您调用Read之前,画布上不会显示任何内容
请参阅Demo_Matplotlib.py您可以复制的食谱。
TKCanvas-不是方法而是属性。返回tkinter画布小部件
您所有的数学迷都将喜欢这个元素…而所有非数学迷都将更喜欢它。
我发现没有什么比从GUI框架处理图形的坐标系有趣的多了。它总是与我想要的东西背道而驰。(0,0)在左上角…。有时…还是在左下角?简而言之,这是一个痛苦的屁股。
如何获得自己的(0,0)位置,然后使用这些坐标而不是tkinter提供的功能呢?这产生了非常强大的功能-以您自己的单位工作,然后在以像素为单位的区域中显示它们。
如果您曾经对绘制的某个表面上的(0,0)位置感到沮丧,请别担心,您的挫败感就在这里结束。您可以使用所需的任何坐标系进行绘制。将(0,0)放置在所需的任何位置,包括不在图表上的任何位置。您可以定义一个图,在X轴上所有负数都在-2.1和-3.5之间,在Y轴上所有负数都在-3到-8.2之间
提供Graph元素需要3个值。他们是:
提供这些值之后,您可以通过创建“图形图”在整个图形上进行涂抹。创建图形图形,并通过调用以下方法获取图形ID:
您可以通过提供图形ID的x,y增量来移动画布上的图形。它不会移动到绝对位置,而是从当前位置偏移。(使用“重定位”移动到特定位置)
graph.MoveFigure(my_circle, 10, 10)
您还将使用此ID删除绘制的单个图形:
graph.DeleteFigure(my_circle)
如果为图形元素启用了事件,则可以接收鼠标单击事件。如果您另外drag_submits在创建Graph Element时启用,那么当您在窗口内“拖动”时,您还将获得事件。“拖动”定义为向下的鼠标左键,然后移动鼠标。
发生拖动事件时,该事件将成为“图形元素”的键。的value中的值返回字典当前鼠标的(X,Y)位置的一个元组。
这意味着您将获得事件的“流”。如果鼠标移动,您将获得至少1个事件,并且可能会超过1个事件。
当你有已经drag_submits启用,有一个棘手的情况是出现…大功告成拖放你放开鼠标按钮的时候会发生什么?“鼠标向上”事件如何传递回您的代码。
“鼠标向上移动”将为您生成一个事件,值: Graph_key+ ‘+UP’。因此,如果Graph Element的键为’GRAPH’,则释放鼠标按钮时将收到的事件是: ‘GRAPH+UP’
是的,这有点奇怪,但是可以。也很简单。我建议在处理这些类型的字符串值时使用.startswith和.endswith内置函数。
此处是一个例子events并且values dictionary这是通过点击和一个图形元素与键==“图形”的拖动内部产生:
graph {'graph': (159, 256)}
graph {'graph': (157, 256)}
graph {'graph': (157, 256)}
graph {'graph': (157, 254)}
graph {'graph': (157, 254)}
graph {'graph': (154, 254)}
graph {'graph': (154, 254)}
graph+UP {'graph': (154, 254)}
表和树元素在PySimpleGUI中最复杂。他们有很多选择和很多不同寻常的特征。
从Window.read“表元素” 的调用返回的值是当前突出显示的行号的列表。
新的PySimpleGUIQt是添加的Table方法Get。此方法返回当前在GUI中显示的表。为了获得用户可能对该表进行的任何编辑,需要使用此方法。
对于tkinter端口,它将返回创建表时传递的相同值,因为用户无法修改tkinter表(如果知道方法,请提交问题)。
一直存在一个难以捉摸的问题,即在单击表标题或其附近时,tkinter会变得疯狂,并在移动鼠标时不断调整列的大小。
自从第一次发布该Table元素以来就存在此问题。它在版本4.3中修复。
过去几个Python版本中发布的tkinter都有一个错误。所有类型的表颜色根本不起作用。行的背景永远不变。如果这对您很重要,则需要降级 Python版本。3.6与PySimpleGUI和tkinter的配合非常好。
如果希望以空表开头,则需要指定一个空表。此列表理解将创建一个包含15行6列的空表。
data = [['' for row in range(15)]for col in range(6)]
有两种方法可以获取从表元素生成的事件。
change_submits作为行上点击,一旦生成的事件 bind_return_key事件产生时,一排被双击或回车键是按下,同时在列。
树元素和表元素是近亲。在表元素中找到的许多参数都适用于树元素。特别是标题信息,列宽等。
与表不同,树没有标准格式。因此,必须构造传递到树元素的数据结构。这是使用TreeData类完成的。流程如下:
获取一个TreeData对象
def TreeData()
def Insert(self, parent, key, text, values, icon=None)
要将数据“插入”到树中,将调用TreeData方法Insert。
Insert(parent_key, key, display_text, values)
要指示在树的开头插入,请使用父键“”。因此,树中的每个顶级节点都会有一个父节点=“”
此代码创建一个TreeData对象并填充3个值
treedata = sg.TreeData()
treedata.Insert("", '_A_', 'A', [1,2,3])
treedata.Insert("", '_B_', 'B', [4,5,6])
treedata.Insert("_A_", '_A1_', 'A1', ['can','be','anything'])
请注意,您可以对display_text和keys使用相同的值。您唯一需要注意的是您不能重复按键。
读取窗口时,表格元素将返回用户选择的行的列表。如果未选择行,则该列表将为空。
如果您希望在树项旁边显示图标,请在的调用中指定该图标Insert。您使用可选icon参数传入文件名或Base64字节字符串。
选项卡是PySimpleGUI的另一个“容器元素”。就像窗口包含布局一样,它能够“包含”布局。其他容器元素包括Column和Frame元素。
就像窗口和其他容器元素一样,Tab元素的布局也包含任何所需布局中元素的任何所需组合。您可以在Windows等内部的“列”内部的“选项卡”内部设置选项卡。
Tab布局看起来与Window布局完全一样,即它们是Elements列表的列表。
将Tab元素放入窗口的方式与所有其他元素不同。 您不能将选项卡直接放置在窗口的布局中。
另外,此时不能使选项卡不可见。它们具有可见性参数,但调用update不会更改它。
选项卡包含在TabGroups中。它们不会放置在其他布局中。要将选项卡放入窗口,请首先将TabElement放入TabGroupElement中,然后将TabGroupElement放入Window布局中。
tab1_layout = [[sg.T('This is inside tab 1')]]
tab2_layout = [[sg.T('This is inside tab 2')],
[sg.In(key='in')]]
整个窗口的布局如下所示:
layout = [[sg.TabGroup([[sg.Tab('Tab 1', tab1_layout), sg.Tab('Tab 2', tab2_layout)]])],
[sg.Button('Read')]]
窗口布局具有TabGroup,在Tab Group中是两个Tab元素。
所有这些容器元素和Windows布局要注意的一件重要事情……它们都采用“列表列表”作为布局。他们都有这样的布局[[ ]]
您将要[[ ]]在调试选项卡式窗口时将此结构牢记在心。忽略一个或两个必要的[
如前所述,旧选项卡仅限于仅在窗口级别。换句话说,选项卡的大小等于整个窗口的大小。“新样式”标签不是这种情况。这就是为什么当您发现旧代码不再适用于新的PySimpleGUI版本时不会感到沮丧的原因。值得花一些时间来转换代码。
看看使用“新标签”可以做什么!
签出选项卡7和8。我们有一个带有列的窗口,其中包含选项卡5和6。在选项卡6上是…选项卡7和8。
从3.8.0版开始,Tab和TabGroup元素的API定义中显示的所有选项都不起作用。他们在那里作为占位符。
首先,我们有选项卡布局定义。它们反映了您在屏幕快照中看到的内容。选项卡1中包含1个文本元素。选项卡2具有文本和输入元素。
现在,当读取返回时,选项卡组将返回一个值。他们返回当前选择的选项卡。enable_events如果选择/更改了该组中的选项卡,则还可以设置一个参数,该参数导致读取返回。属于切换到的选项卡的键或标题将作为值返回
x ##窗格元素
Pane Element是3.20版中的新功能,它是超酷的tkinter功能。您不会在PySimpleGUIQt中找到此对象,只有PySimpleGUI。很难描述这些事情之一。可以将它们视为可以滑动的“无标签的标签”。
窗格元素的每个“窗格”都必须是列元素。该参数pane_list是列元素的列表。
如果您尝试内联声明所有内容,则调用可能会显得有些毛茸茸,如本例所示。
sg.Pane([col5, sg.Column([[sg.Pane([col1, col2, col4], handle_size=15, orientation='v', background_color=None, show_handle=True, visible=True, key='_PANE_', border_width=0, relief=sg.RELIEF_GROOVE),]]),col3 ], orientation='h', background_color=None, size=(160,160), relief=sg.RELIEF_RAISED, border_width=0)
结合可见性可以创建一个有趣的界面,整个窗格从视图中隐藏起来,直到用户需要为止。这是产生“动态”窗口的一种方法。
从2.5版开始,您可以更改窗口和Elements的背景颜色。
您的窗口可以从此:
为此…通过一个函数调用…
虽然您可以逐个元素或逐个窗口级别进行操作,但更简单的方法是使用theme调用或set_options。这些调用将为创建的所有窗口设置颜色。
请注意,一旦更改了这些选项,它们就会在程序的其余执行过程中被更改。您所有的窗口都将具有该主题,直到您将其更改为其他主题为止。
该调用设置了许多不同的颜色选项。
SetOptions(background_color='#9FB8AD',
text_element_background_color='#9FB8AD',
element_background_color='#9FB8AD',
scrollbar_color=None,
input_elements_background_color='#F7F3EC',
progress_meter_color = ('green', 'blue')
button_color=('white','#475841'))
除了运行普通窗口外,现在还可以在系统托盘中放下一个图标,您可以阅读该图标来获取菜单事件。有一个新的SystemTray对象,其用法与Window对象非常相似。您首先得到一个,然后执行读取以获取事件。
虽然只有PySimpleGUIQt和PySimpleGUIWx提供了真正的“系统任务栏”功能,但有一个模拟的系统任务栏功能已在2020年用于PySimpleGUI的tkinter版本。所有相同的对象和方法调用都是相同的,其效果与Wx和Qt版本所看到的非常相似。该图标位于窗口的右下角。设置它的位置尚未公开,但是您可以将其拖动到屏幕上的其他位置。
用完全相同的源代码支持Wx,Qt和tkinter的想法非常吸引人,并且是开发tkinter版本的原因之一。您可以通过简单地将import语句更改为这三个端口中的任何一个来切换框架。
tkinter版本显示的气球与实际系统任务栏图标显示的消息气球不同。而是显示一个漂亮的半透明窗口。此窗口将淡入/淡出,其设计与ptoaster软件包中的窗口相同。
这是SystemTray对象的定义。
SystemTray(menu=None, filename=None, data=None, data_base64=None, tooltip=None, metadata=None):
'''
SystemTray - create an icon in the system tray
:param menu: Menu definition
:param filename: filename for icon
:param data: in-ram image for icon
:param data_base64: basee-64 data for icon
:param tooltip: tooltip string
:param metadata: (Any) User metadata that can be set to ANYTHING
'''
您会注意到,有3种不同的方法来指定图标图像。base-64参数允许您在.py代码中定义一个作为已编码图像的变量,因此您不需要任何其他文件。非常方便的功能。
系统托盘设计模式
这是您可以用来快速入门的设计模式。
该程序将创建系统任务栏图标并执行阻止读取。如果从系统托盘中选择了“打开”项目,则会显示一个弹出窗口。
可以在任何桌面版本的PySimpleGUI(tkinter,Qt,WxPython)上执行相同的代码
import PySimpleGUIQt as sg
# import PySimpleGUIWx as sg
# import PySimpleGUI as sg
menu_def = ['BLANK', ['&Open', '---', '&Save', ['1', '2', ['a', 'b']], '&Properties', 'E&xit']]
tray = sg.SystemTray(menu=menu_def, filename=r'default_icon.ico')
while True: # The event loop
menu_item = tray.read()
print(menu_item)
if menu_item == 'Exit':
break
elif menu_item == 'Open':
sg.popup('Menu item chosen', menu_item)
在PySimpleGUI(tkinter版本)上运行时,系统任务栏图标为PNG和GIF格式。PNG,GIF和ICO格式适用于Wx和Qt端口。
指定“图标”时,可以使用3种不同的格式。* filename-文件名* data_base64-base64字节字符串*’ data-内存中位图或其他“原始”图像
您将在initialize语句和Update方法上找到3个用于指定这3个选项的参数。
为了进行测试,您可能会发现使用内置的PySimpleGUI图标可以很好地开始确保在引入外部图像资产之前已正确编码了所有内容。如果您的图标文件有问题,它将快速告诉您。要使用默认图标运行,请使用以下类似方法来创建系统托盘:
tray = sg.SystemTray(menu=menu_def, data_base64=sg.DEFAULT_BASE64_ICON)
menu_def = ['BLANK', ['&Open', '&Save', ['1', '2', ['a', 'b']], '!&Properties', 'E&xit']]
使用列表定义菜单。“菜单项”是一个字符串,它指定:显示的文本键盘快捷键*键
有关在菜单上使用按键的更多信息,请参见菜单按键部分。
没有按键和键盘快捷键的条目是一个简单的字符串 ‘Menu Item’
如果要使“ M”成为键盘快捷键,请放置一个 &在快捷键字母前。 ‘&Menu Item’
您可以添加“键”以使菜单项唯一,或作为显示菜单文本的另一种方式来标识菜单项。通过将键放置::在文本之后,将其添加到文本部分。
'Menu Item::key'
第一个条目可以忽略。'BLANK在此示例中选择了“。之所以这样,是因为通常您会在菜单栏上的某些标题下指定这些菜单。但是这里没有标题,因此您可以用所需的任何值填充它。
分隔符 如果要在两个项目之间使用分隔符,请添加该条目’—’,它将在菜单中的该位置添加一个分隔符项目。
如果要禁用菜单项,请!在菜单项之前放置一个
读取-读取上下文菜单或检查事件
def Read(timeout=None)
'''
Reads the context menu
:param timeout: Optional. Any value other than None indicates a non-blocking read
:return: String representing meny item chosen. None if nothing read.
'''
该timeout参数指定事件等待多长时间。如果在超时时间内没有任何反应,则返回“超时事件”。这些类型的读取使得可以异步运行。要不受阻碍地运行,请指定timeout=0在Read调用中。
读取返回所选菜单项的菜单文本(含键)。如果您指定Open::key为菜单项,并且用户单击了Open,则Open::key在完成读取后,您将收到字符串。
除菜单项外,“读取”调用还可以返回几个特殊值。它们包括:
EVENT_SYSTEM_TRAY_ICON_DOUBLE_CLICKED-双击托盘图标EVENT_SYSTEM_TRAY_ICON_ACTIVATED-单击托盘图标EVENT_SYSTEM_TRAY_MESSAGE_CLICKED-单击消息气球,如果没有设置超时值的事件,则返回TIMEOUT_KEY
隐藏图标。请注意,隐藏图标时不会显示任何消息气球。
def Hide()
做与隐藏相同的事情
def Close()
显示一个以前隐藏的图标
def UnHide()
在系统任务栏区域中的图标上方显示气球。您可以指定自己的图标以显示在气球中,也可以设置messageicon为预设值之一。
SYSTEM_TRAY_MESSAGE_ICON_INFORMATION
SYSTEM_TRAY_MESSAGE_ICON_WARNING
SYSTEM_TRAY_MESSAGE_ICON_CRITICAL
SYSTEM_TRAY_MESSAGE_ICON_NOICON
ShowMessage(title, message, filename=None, data=None, data_base64=None, messageicon=None, time=10000):
'''
Shows a balloon above icon in system tray
:param title: Title shown in balloon
:param message: Message to be displayed
:param filename: Optional icon filename
:param data: Optional in-ram icon
:param data_base64: Optional base64 icon
:param time: How long to display message in milliseconds :return:
'''
注意,在Windows上可能需要更改注册表以使消息提示框可见。要解决此问题,您必须创建在此屏幕截图中看到的DWORD
您可以在SystemTray对象中更新这些项目中的任何一项菜单定义图标*工具提示
tkinter端口除了能够通过系统托盘显示消息外,还具有无需定义系统托盘对象即可显示系统托盘消息的附加功能。您可以简单地显示一个通知窗口。这也许消除了使用ptoaster软件包的需要?
该方法是“类方法”,这意味着您可以直接调用它,而无需先创建该对象的实例化。要显示通知窗口,请致电SystemTray.notify。
`sg.SystemTray.notify('Notification Title', 'This is the notification` message')
这是一个阻塞的呼叫,因此,如果您要淡入淡出窗口,则可能需要花费几秒钟的时间。有一些选项可控制淡入淡出,显示内容的时间,alpha通道等。请参阅本文档末尾的呼叫签名。