164 lines
6.8 KiB
Markdown
164 lines
6.8 KiB
Markdown
|
|
# PySimpleGUI:使用多个窗口
|
|||
|
|
|
|||
|
|
> 原文:<https://www.blog.pythonlibrary.org/2021/01/20/pysimplegui-working-with-multiple-windows/>
|
|||
|
|
|
|||
|
|
当你创建图形用户界面(GUI)时,你经常会发现你需要创建不止一个窗口。在本教程中,您将学习如何使用 [PySimpleGUI](https://pysimplegui.readthedocs.io/en/latest/) 创建两个窗口。
|
|||
|
|
|
|||
|
|
PySimpleGUI 是最容易上手的 Python GUIs 之一。它包装了其他 Python GUIs,并为它们提供了一个公共接口。你可以在我的[PySimpleGUI 简介](https://www.blog.pythonlibrary.org/2019/10/23/a-brief-intro-to-pysimplegui/)或者我的文章《真正的 Python, [PySimpleGUI:用 Python 创建 GUI 的简单方法](https://realpython.com/pysimplegui-python/)中读到更多。
|
|||
|
|
|
|||
|
|
#### 入门指南
|
|||
|
|
|
|||
|
|
您需要安装 PySimpleGUI 来开始使用它。您可以使用画中画来做到这一点:
|
|||
|
|
|
|||
|
|
```py
|
|||
|
|
python -m pip install pysimplegui
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
#### 使窗口模式化
|
|||
|
|
|
|||
|
|
PySimpleGUI 提供了一个**窗口**元素,用于显示其他元素,比如按钮、文本、图像等等。这些窗口可以是模态的。模式窗口不允许你与程序中的其他窗口交互,直到你退出它。当你想强迫用户读一些东西或者问用户一个问题时,这是很有用的。例如,一个模态对话框可以用来询问用户是否真的想退出你的程序,或者显示一个最终用户协议(EULA)对话框。
|
|||
|
|
|
|||
|
|
您可以创建两个窗口,并在 PySimpleGUI 中同时显示它们,如下所示:
|
|||
|
|
|
|||
|
|
```py
|
|||
|
|
import PySimpleGUI as sg
|
|||
|
|
|
|||
|
|
def open_window():
|
|||
|
|
layout = [[sg.Text("New Window", key="new")]]
|
|||
|
|
window = sg.Window("Second Window", layout, modal=True)
|
|||
|
|
choice = None
|
|||
|
|
while True:
|
|||
|
|
event, values = window.read()
|
|||
|
|
if event == "Exit" or event == sg.WIN_CLOSED:
|
|||
|
|
break
|
|||
|
|
|
|||
|
|
window.close()
|
|||
|
|
|
|||
|
|
def main():
|
|||
|
|
layout = [[sg.Button("Open Window", key="open")]]
|
|||
|
|
window = sg.Window("Main Window", layout)
|
|||
|
|
while True:
|
|||
|
|
event, values = window.read()
|
|||
|
|
if event == "Exit" or event == sg.WIN_CLOSED:
|
|||
|
|
break
|
|||
|
|
if event == "open":
|
|||
|
|
open_window()
|
|||
|
|
|
|||
|
|
window.close()
|
|||
|
|
|
|||
|
|
if __name__ == "__main__":
|
|||
|
|
main()
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
当您运行这段代码时,您会看到一个小的主窗口,如下所示:
|
|||
|
|
|
|||
|
|

|
|||
|
|
|
|||
|
|
如果你点击“打开窗口”按钮,你会得到一个新的窗口,看起来像这样:
|
|||
|
|
|
|||
|
|

|
|||
|
|
|
|||
|
|
第二个窗口中有一个名为*模态*的参数,它被设置为**真**。这意味着在关闭第二个窗口之前,您无法与第一个窗口进行交互。
|
|||
|
|
|
|||
|
|
现在让我们来看一种方法,如果你正在创建一个像上面这样的简单窗口,你可以缩短你的代码。
|
|||
|
|
|
|||
|
|
#### 创建内嵌的新窗口
|
|||
|
|
|
|||
|
|
你不必为你的第二窗口写一个完全独立的函数。如果你不想在第二个窗口中有很多小部件,那么你可以创建一个一行或两行的窗口。
|
|||
|
|
|
|||
|
|
有一种方法可以做到:
|
|||
|
|
|
|||
|
|
```py
|
|||
|
|
import PySimpleGUI as sg
|
|||
|
|
|
|||
|
|
def main():
|
|||
|
|
layout = [[sg.Button("Open Window", key="open")]]
|
|||
|
|
window = sg.Window("Main Window", layout)
|
|||
|
|
while True:
|
|||
|
|
event, values = window.read()
|
|||
|
|
if event == "Exit" or event == sg.WIN_CLOSED:
|
|||
|
|
break
|
|||
|
|
if event == "open":
|
|||
|
|
if sg.Window("Other Window", [[sg.Text("Try Again?")],
|
|||
|
|
[sg.Yes(), sg.No()]]).read(close=True)[0] == "Yes":
|
|||
|
|
print("User chose yes!")
|
|||
|
|
else:
|
|||
|
|
print("User chose no!")
|
|||
|
|
|
|||
|
|
window.close()
|
|||
|
|
|
|||
|
|
if __name__ == "__main__":
|
|||
|
|
main()
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
在本例中,当您单击“打开窗口”按钮时,它会在条件语句中创建第二个窗口。该窗口直接调用 **read()** ,当用户选择“是”、“否”或退出窗口时关闭。根据用户的选择,条件将打印出不同的内容。
|
|||
|
|
|
|||
|
|
#### 传统的多窗口设计模式
|
|||
|
|
|
|||
|
|
PySimpleGUI 有一个推荐的方法来处理多个窗口。在他们的[食谱](https://pysimplegui.readthedocs.io/en/latest/cookbook/#multiple-windows)和 Github 上的[演示中提到了这一点。这里有一个来自**的例子 Demo _ Design _ Pattern _ Multiple _ windows . py:**](https://github.com/PySimpleGUI/PySimpleGUI/tree/master/DemoPrograms)
|
|||
|
|
|
|||
|
|
```py
|
|||
|
|
import PySimpleGUI as sg
|
|||
|
|
"""
|
|||
|
|
Demo - 2 simultaneous windows using read_all_window
|
|||
|
|
|
|||
|
|
Window 1 launches window 2
|
|||
|
|
BOTH remain active in parallel
|
|||
|
|
|
|||
|
|
Both windows have buttons to launch popups. The popups are "modal" and thus no other windows will be active
|
|||
|
|
|
|||
|
|
Copyright 2020 PySimpleGUI.org
|
|||
|
|
"""
|
|||
|
|
|
|||
|
|
def make_win1():
|
|||
|
|
layout = [[sg.Text('This is the FIRST WINDOW'), sg.Text(' ', k='-OUTPUT-')],
|
|||
|
|
[sg.Text('Click Popup anytime to see a modal popup')],
|
|||
|
|
[sg.Button('Launch 2nd Window'), sg.Button('Popup'), sg.Button('Exit')]]
|
|||
|
|
return sg.Window('Window Title', layout, location=(800,600), finalize=True)
|
|||
|
|
|
|||
|
|
def make_win2():
|
|||
|
|
layout = [[sg.Text('The second window')],
|
|||
|
|
[sg.Input(key='-IN-', enable_events=True)],
|
|||
|
|
[sg.Text(size=(25,1), k='-OUTPUT-')],
|
|||
|
|
[sg.Button('Erase'), sg.Button('Popup'), sg.Button('Exit')]]
|
|||
|
|
return sg.Window('Second Window', layout, finalize=True)
|
|||
|
|
|
|||
|
|
window1, window2 = make_win1(), None # start off with 1 window open
|
|||
|
|
|
|||
|
|
while True: # Event Loop
|
|||
|
|
window, event, values = sg.read_all_windows()
|
|||
|
|
if event == sg.WIN_CLOSED or event == 'Exit':
|
|||
|
|
window.close()
|
|||
|
|
if window == window2: # if closing win 2, mark as closed
|
|||
|
|
window2 = None
|
|||
|
|
elif window == window1: # if closing win 1, exit program
|
|||
|
|
break
|
|||
|
|
elif event == 'Popup':
|
|||
|
|
sg.popup('This is a BLOCKING popup','all windows remain inactive while popup active')
|
|||
|
|
elif event == 'Launch 2nd Window' and not window2:
|
|||
|
|
window2 = make_win2()
|
|||
|
|
elif event == '-IN-':
|
|||
|
|
window['-OUTPUT-'].update(f'You enetered {values["-IN-"]}')
|
|||
|
|
elif event == 'Erase':
|
|||
|
|
window['-OUTPUT-'].update('')
|
|||
|
|
window['-IN-'].update('')
|
|||
|
|
window.close()
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
当您运行这段代码时,您可以打开几个不同的窗口,如下所示:
|
|||
|
|
|
|||
|
|

|
|||
|
|
|
|||
|
|
你会想尝试使用这两种方法,看看哪种最适合你。这个方法的好处是只有一个事件循环,这简化了事情。
|
|||
|
|
|
|||
|
|
#### 包扎
|
|||
|
|
|
|||
|
|
PySimpleGUI 允许您创建简单和复杂的用户界面。虽然这里没有涉及,但是您也可以使用 **sg.popup()** 向用户显示一个更简单的对话框。这些对话框也可以是模态的,但不像常规窗口那样可以完全自定义。
|
|||
|
|
|
|||
|
|
试试 PySimpleGUI,看看你的想法。
|
|||
|
|
|
|||
|
|
#### 相关阅读
|
|||
|
|
|
|||
|
|
* [PySimpleGUI 简介](https://www.blog.pythonlibrary.org/2019/10/23/a-brief-intro-to-pysimplegui/)
|
|||
|
|
* 【PySimpleGUI 的演示
|
|||
|
|
* 真正的 Python - [PySimpleGUI:用 Python 创建 GUI 的简单方法](https://realpython.com/pysimplegui-python/)
|