023——搭建图形化客户端(基于pySimpleGUI)

目录

一、pysimplegui

1.1 安装

1.2 测试

二、 pysimplegui学习

2.1 学习地址 

2.2 人类早期驯服pysimplegui珍贵流水账

三、 实现项目专属的界面


一、pySimpleGUI

1.1 安装

pip install pysimplegui -i https://pypi.tuna.tsinghua.edu.cn/simple

Command 'pip' not found, but can be installed with:

apt install python-pip
Please ask your administrator.

报错只需要安装一下pip就行

1.2 测试

这个图形化库还依赖另一个库

Traceback (most recent call last):
  File "test_pysimplegui.py", line 1, in <module>
    import PySimpleGUI as sg  
  File "/home/book/.local/lib/python3.8/site-packages/PySimpleGUI/__init__.py", line 1, in <module>
    from .PySimpleGUI import *
  File "/home/book/.local/lib/python3.8/site-packages/PySimpleGUI/PySimpleGUI.py", line 84, in <module>
    import tkinter as tk
ModuleNotFoundError: No module named 'tkinter'

sudo apt-get install python3-tk

这个包5.0以后开始收费了

先卸载然后验证一下

这样就证明卸载成功了

然后

pip install PySimpleGUI==4.14.1 -i https://pypi.tuna.tsinghua.edu.cn/simple

简单测试了一下木有问题呢

import PySimpleGUI as sg  
  
# 定义窗口布局  
layout = [  
    [sg.Text("Hello PySimpleGUI")],  
    [sg.Button("Click Me")],  
    [sg.Output(size=(40, 10))]  
]  
  
# 创建窗口  
window = sg.Window('Test PySimpleGUI', layout)  
  
# 事件循环  
while True:  
    event, values = window.read()  
    if event == sg.WIN_CLOSED or event == 'Exit':  # 如果点击了窗口关闭按钮或者用户选择了退出  
        break  
    if event == 'Click Me':  # 如果点击了按钮  
        window['Output'].update('Button clicked!')  # 在输出区域更新消息  
  
# 关闭窗口  
window.close()

二、 pySimpleGUI学习

2.1 学习地址 



PyPI · The Python Package Index

没找到4.14.1.

先按照4.60学习

这个太卡了也可以不看这个,不过这个是官方的所以比较权威

The Project - PySimpleGUI Documentation

https://github.com/PySimpleGUI/PySimpleGUI

这个库是一个上层的库,它支持调用下面四个底层库,默认是TKinter。我们项目中用的也是这个

2.2 人类早期驯服pySimpleGUI珍贵流水账

有很多的资料,我觉得最快的还是直接看demo

不过会遇到很多问题,因为我们下载的不是最新版。好多方法老版本木有的

比如这个问题

import PySimpleGUI as sg

"""
    Demo - Element List

    All elements shown in 1 window as simply as possible.

    Copyright 2022-2023 PySimpleSoft, Inc. and/or its licensors. All rights reserved.
    
    Redistribution, modification, or any other use of PySimpleGUI or any portion thereof is subject to the terms of the PySimpleGUI License Agreement available at https://eula.pysimplegui.com.
    
    You may not redistribute, modify or otherwise use PySimpleGUI or its contents except pursuant to the PySimpleGUI License Agreement.
"""


use_custom_titlebar = True if sg.running_trinket() else False

def make_window(theme=None):

    NAME_SIZE = 23


    def name(name):
        dots = NAME_SIZE-len(name)-2
        return sg.Text(name + ' ' + '•'*dots, size=(NAME_SIZE,1), justification='r',pad=(0,0), font='Courier 10')

    sg.theme(theme)

    # NOTE that we're using our own LOCAL Menu element
    if use_custom_titlebar:
        Menu = sg.MenubarCustom
    else:
        Menu = sg.Menu

    treedata = sg.TreeData()

    treedata.Insert("", '_A_', 'Tree Item 1', [1234], )
    treedata.Insert("", '_B_', 'B', [])
    treedata.Insert("_A_", '_A1_', 'Sub Item 1', ['can', 'be', 'anything'], )

    layout_l = [
                [name('Text'), sg.Text('Text')],
                [name('Input'), sg.Input(s=15)],
                [name('Multiline'), sg.Multiline(s=(15,2))],
                [name('Output'), sg.Output(s=(15,2))],
                [name('Combo'), sg.Combo(sg.theme_list(), default_value=sg.theme(), s=(15,22), enable_events=True, readonly=True, k='-COMBO-')],
                [name('OptionMenu'), sg.OptionMenu(['OptionMenu',],s=(15,2))],
                [name('Checkbox'), sg.Checkbox('Checkbox')],
                [name('Radio'), sg.Radio('Radio', 1)],
                [name('Spin'), sg.Spin(['Spin',], s=(15,2))],
                [name('Button'), sg.Button('Button')],
                [name('ButtonMenu'), sg.ButtonMenu('ButtonMenu', sg.MENU_RIGHT_CLICK_EDITME_EXIT)],
                [name('Slider'), sg.Slider((0,10), orientation='h', s=(10,15))],
                [name('Listbox'), sg.Listbox(['Listbox', 'Listbox 2'], no_scrollbar=True,  s=(15,2))],
                [name('Image'), sg.Image(sg.EMOJI_BASE64_HAPPY_THUMBS_UP)],
                [name('Graph'), sg.Graph((125, 50), (0,0), (125,50), k='-GRAPH-')]  ]

    layout_r  = [[name('Canvas'), sg.Canvas(background_color=sg.theme_button_color()[1], size=(125,40))],
                [name('ProgressBar'), sg.ProgressBar(100, orientation='h', s=(10,20), k='-PBAR-')],
                [name('Table'), sg.Table([[1,2,3], [4,5,6]], ['Col 1','Col 2','Col 3'], num_rows=2)],
                [name('Tree'), sg.Tree(treedata, ['Heading',], num_rows=3)],
                [name('Horizontal Separator'), sg.HSep()],
                [name('Vertical Separator'), sg.VSep()],
                [name('Frame'), sg.Frame('Frame', [[sg.T(s=15)]])],
                [name('Column'), sg.Column([[sg.T(s=15)]])],
                [name('Tab, TabGroup'), sg.TabGroup([[sg.Tab('Tab1',[[sg.T(s=(15,2))]]), sg.Tab('Tab2', [[]])]])],
                [name('Pane'), sg.Pane([sg.Col([[sg.T('Pane 1')]]), sg.Col([[sg.T('Pane 2')]])])],
                [name('Push'), sg.Push(), sg.T('Pushed over')],
                [name('VPush'), sg.VPush()],
                [name('Sizer'), sg.Sizer(1,1)],
                [name('StatusBar'), sg.StatusBar('StatusBar')],
                [name('Sizegrip'), sg.Sizegrip()]  ]

    # Note - LOCAL Menu element is used (see about for how that's defined)
    layout = [[Menu([['File', ['Exit']], ['Edit', ['Edit Me', ]]],  k='-CUST MENUBAR-',p=0)],
              [sg.T('PySimpleGUI Elements - Use Combo to Change Themes', font='_ 14', justification='c', expand_x=True)],
              [sg.Checkbox('Use Custom Titlebar & Menubar', use_custom_titlebar, enable_events=True, k='-USE CUSTOM TITLEBAR-', p=0)],
              [sg.Col(layout_l, p=0), sg.Col(layout_r, p=0)]]

    window = sg.Window('The PySimpleGUI Element List', layout, finalize=True, right_click_menu=sg.MENU_RIGHT_CLICK_EDITME_VER_EXIT, keep_on_top=True, use_custom_titlebar=use_custom_titlebar)

    window['-PBAR-'].update(30)                                                     # Show 30% complete on ProgressBar
    window['-GRAPH-'].draw_image(data=sg.EMOJI_BASE64_HAPPY_JOY, location=(0,50))   # Draw something in the Graph Element

    return window


window = make_window()

while True:
    event, values = window.read()
    # sg.Print(event, values)
    if event == sg.WIN_CLOSED or event == 'Exit':
        break

    if values['-COMBO-'] != sg.theme():
        sg.theme(values['-COMBO-'])
        window.close()
        window = make_window()
    if event == '-USE CUSTOM TITLEBAR-':
        use_custom_titlebar = values['-USE CUSTOM TITLEBAR-']
        sg.set_options(use_custom_titlebar=use_custom_titlebar)
        window.close()
        window = make_window()
    if event == 'Edit Me':
        sg.execute_editor(__file__)
    elif event == 'Version':
        sg.popup_scrolled(__file__, sg.get_versions(), keep_on_top=True, non_blocking=True)
window.close()

从名字上看我觉得它只是想验证他的依赖库是不是安装了

给他改成直接等于true

改成flase也会报错

一顿修算是勉强能跑起来了

import PySimpleGUI as sg

def make_window(theme=None):
    NAME_SIZE = 23
    def name(name):
        dots = NAME_SIZE-len(name)-2
        return sg.Text(name + ' ' + '•'*dots, size=(NAME_SIZE,1), justification='r',pad=(0,0), font='Courier 10')

    sg.theme(theme)
    Menu = sg.Menu
    menu_def = [['File', ['Open', 'Save', 'Exit']], ['Edit', ['Copy', 'Paste']]]
    treedata = sg.TreeData()

    treedata.Insert("", '_A_', 'Tree Item 1', [1234], )
    treedata.Insert("", '_B_', 'B', [])
    treedata.Insert("_A_", '_A1_', 'Sub Item 1', ['can', 'be', 'anything'], )
    s1=15
    s2=(15,2)
    use_custom_titlebar=False
    layout_l = [
                [name('Text'), sg.Text('Text')],
                [name('Input'), sg.Input(s1)],
                [name('Multiline'), sg.Multiline(s2)],
                [name('Output'), sg.Output(s2)],
                [name('Combo'), sg.Combo(sg.theme_list(), default_value=sg.theme(), size=(15,22), enable_events=True, readonly=True, key='-COMBO-')],
                [name('OptionMenu'), sg.OptionMenu(['OptionMenu',],s2)],
                [name('Checkbox'), sg.Checkbox('Checkbox')],
                [name('Radio'), sg.Radio('Radio', 1)],
                [name('Spin'), sg.Spin(['Spin',], s2)],
                [name('Button'), sg.Button('Button')],
                #[name('ButtonMenu'), sg.ButtonMenu('ButtonMenu'), ['Open', 'Save', 'Exit']],
                [name('Slider'), sg.Slider((0,10), orientation='h', size=(10,15))],
                [name('Listbox'), sg.Listbox(['Listbox', 'Listbox 2'], no_scrollbar=True,  size=(15,2))],
                #[name('Image'), sg.Image(sg.EMOJI_BASE64_HAPPY_THUMBS_UP)],
                [name('Graph'), sg.Graph((125, 50), (0,0), (125,50), key='-GRAPH-')]  ]

    layout_r  = [[name('Canvas'), sg.Canvas(background_color=sg.theme_button_color()[1], size=(125,40))],
                [name('ProgressBar'), sg.ProgressBar(100, orientation='h', size=(10,20), key='-PBAR-')],
                [name('Table'), sg.Table([[1,2,3], [4,5,6]], ['Col 1','Col 2','Col 3'], num_rows=2)],
                [name('Tree'), sg.Tree(treedata, ['Heading',], num_rows=3)],
                #[name('Horizontal Separator'), sg.HSep()],
                [name('Vertical Separator'), sg.VSep()],
                [name('Frame'), sg.Frame('Frame', [[sg.T(s1)]])],
                [name('Column'), sg.Column([[sg.T(s1)]])],
                [name('Tab, TabGroup'), sg.TabGroup([[sg.Tab('Tab1',[[sg.T(s2)]]), sg.Tab('Tab2', [[]])]])],
                [name('Pane'), sg.Pane([sg.Col([[sg.T('Pane 1')]]), sg.Col([[sg.T('Pane 2')]])])],
                #[name('Push'), sg.Push(), sg.T('Pushed over')],
                #[name('VPush'), sg.VPush()],
                [name('Sizer'), sg.Sizer(1,1)],
                [name('StatusBar'), sg.StatusBar('StatusBar')],
                #[name('Sizegrip'), sg.Sizegrip()]  
                ]

    # Note - LOCAL Menu element is used (see about for how that's defined)
    layout = [[Menu([['File', ['Exit']], ['Edit', ['Edit Me', ]]],  key='-CUST MENUBAR-')],
              [sg.T('PySimpleGUI Elements - Use Combo to Change Themes', font='_ 14', justification='c')],
              [sg.Checkbox('Use Custom Titlebar & Menubar', use_custom_titlebar, enable_events=True, key='-USE CUSTOM TITLEBAR-')],
              [sg.Col(layout_l), sg.Col(layout_r)]]

    window = sg.Window('The PySimpleGUI Element List', layout, finalize=True, keep_on_top=True)

    window['-PBAR-'].update(30)                                                     # Show 30% complete on ProgressBar
    window['-GRAPH-'].draw_image(location=(0,50))   # Draw something in the Graph Element

    return window

window = make_window()

while True:
    event, values = window.read()
    # sg.Print(event, values)
    if event == sg.WIN_CLOSED or event == 'Exit':
        break

    if values['-COMBO-'] != sg.theme():
        sg.theme(values['-COMBO-'])
        window.close()
        window = make_window()
    if event == '-USE CUSTOM TITLEBAR-':
        use_custom_titlebar = values['-USE CUSTOM TITLEBAR-']
        sg.set_options(use_custom_titlebar=use_custom_titlebar)
        window.close()
        window = make_window()
    if event == 'Edit Me':
        sg.execute_editor(__file__)
    elif event == 'Version':
        sg.popup_scrolled(__file__, sg.get_versions(), keep_on_top=True, non_blocking=True)
window.close()

慎用吧好多功能和API文档描述不一致因为版本不一样。

三、 实现项目专属的界面

'''
fuction : 客户端界面
author  : 辛天宇
data    : 2024-4-12
-------------------------------
author data  modify

'''
import PySimpleGUI as sg

# 全局变量
# 对齐长度
NAME_SIZE = 23

# name 对齐函数
def name(name):
    dots = NAME_SIZE-len(name)-2
    return sg.Text(name + ' ' + '•'*dots, size=(NAME_SIZE,1), justification='r',pad=(0,0), font='Courier 10')

def show_window(theme):
    # 是否使用自定义标题栏
    use_custom_titlebar = False
    # 设置主题
    sg.theme(theme)
    # 创建菜单
    Menu = sg.Menu
    # 左面layout
    layout_l =  [
                    [name('Text'), sg.Text('Text')],
                ]
    #右面layout
    layout_r  = [
                    [name('Text'), sg.Text('Text')],
                ]


    layout = [
                [Menu([['File', ['Exit']], ['Edit', ['Edit Me', ]]],  key='-CUST MENUBAR-')],
                [sg.T('Chip Evaluation Board Self-test System', font='_ 14', justification='c')],
                [sg.Checkbox('Use Custom Titlebar & Menubar', use_custom_titlebar, enable_events=True, key='-USE CUSTOM TITLEBAR-')],
                [sg.Col(layout_l), sg.Col(layout_r)]
            ]

    window = sg.Window('The PySimpleGUI Element List', layout, finalize=True, keep_on_top=True)

    # 事件循环  
    while True:  
        event, values = window.read()  
        if event == sg.WIN_CLOSED or event == 'Exit':  
            break  
        elif event == '-USE CUSTOM TITLEBAR-':  
            # 这里可以添加处理自定义标题栏的逻辑  
            print(f"Use Custom Titlebar: {values['-USE CUSTOM TITLEBAR']}")  
        # 处理其他事件...  

def main():
    # theme参考/client/README
    while True:
        show_window('DefaultNoMoreNagging')

if __name__ == '__main__':
    main()

有个bug打印的时候会重定向到output这个框里无语了

合理利用bug哈哈哈哈哈哈。

暂时就先这样吧后面联调时在处理具体业务。

'''
fuction : 客户端界面
author  : 辛天宇
data    : 2024-4-12
-------------------------------
author data  modify

'''
import PySimpleGUI as sg

# 全局变量
# 项目名称
TOPIC = 'Chip Evaluation Board Self-test System'
# 对齐长度
NAME_SIZE = 23
# 服务器IP
SERVER_IP = "192.168.5.10"
# 温度
TEM = 28
# 湿度
HUM = 25

# name 对齐函数
def name(name):
    dots = NAME_SIZE-len(name)-2
    return sg.Text(name + ' ' + '•'*dots, size=(NAME_SIZE,1), justification='r',pad=(0,0), font='Courier 10')

def add_stars_to_string(s, n):  
    return '*'*n + s + '*'*n  

def show_window(theme):
    # 是否使用自定义标题栏
    use_custom_titlebar = False
    # 设置主题
    sg.theme(theme)
    # 创建菜单
    Menu = sg.Menu
    # 左部layout
    layout_l =  [
                    [name('NetWork'), sg.Button('Connect', key='Connect')],
                    [name('NetWork'), sg.Button('Disconnect', key='Disconnect')],
                    [name('NetWork'), sg.Output(size=(32, 1), key='IP')],
                    [name('Getvalue'), sg.Output(size=(32, 1), key='Getvalue')]
                ]
    # 右部layout
    layout_r  = [
                    [name('Text'), sg.Button('LED', key='LED')],
                    [name('Text'), sg.Button('SR501', key='SR501')],
                    [name('Text'), sg.Button('SR04', key='SR04')],
                    [name('Text'), sg.Button('irda', key='irda')],
                    [name('Text'), sg.Button('motor', key='motor')],
                    [name('Text'), sg.Button('dht11', key='dht11')],
                    [name('Text'), sg.Button('ds18b20', key='ds18b20')],
                    [name('Text'), sg.Button('IIC', key='IIC')],
                    [name('Text'), sg.Button('SPI', key='SPI')],
                ]
    # 修饰
    topic = add_stars_to_string(TOPIC, 5)
    # 设置字体为14号,无特殊样式,通常字体名称和大小用元组表示  
    topic_font = ('_', 24)
    # 整体layout
    layout = [
                [sg.T(topic, text_color='blue', justification='c', font=topic_font)],
                # [sg.Checkbox('Use Custom Titlebar & Menubar', use_custom_titlebar, enable_events=True, key='-USE CUSTOM TITLEBAR-')],
                [sg.Col(layout_l), sg.Col(layout_r)],
                [sg.Text('Output:', size=(7,1), justification='r',pad=(0,0), font='Courier 10'),],
                [sg.Output(size=(96, 8), key='Output')],
                [sg.Button('Quit', key='Quit')]
            ]

    window = sg.Window('The PySimpleGUI Element List', layout, finalize=True, keep_on_top=True)

    # 事件循环  
    while True:  
        try:
            event, values = window.read()
            if event == 'Exit':  
                break
            if event == 'dht11':
                message = f"{TEM}°C   {HUM}%"
                window['Getvalue'].update(message)
            if event == 'ds18b20':
                message = f"{TEM}°C"
                window['Getvalue'].update(message)
            elif event == 'Quit':  
                print(f"See you.............")
                break
            elif event == 'Connect':
                SERVER_IP = "192.168.5.10"
                window['IP'].update(SERVER_IP)
            elif event == 'Disconnect':  
                SERVER_IP = "connectionless network service"
                window['IP'].update(SERVER_IP)
            elif event is None:
                print(f"xxxxxxxxxxxxxxxxxxxx")
                break
            elif event == 'LED':  
                print(f"LED-----------------") 
            # 处理其他事件...
        except Exception as e:
            window.close()
            print(f"An error occurred: {e}")
            return 0
    window.close()
    return 0  

def main():
    # theme参考/client/README
    if 0 == show_window('DefaultNoMoreNagging'):
        return

if __name__ == '__main__':
    main()

  • 28
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

宇努力学习

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值