0%

Python-GUI图形界面开发

Python 进行 GUI 界面开发的相关实践。如:

  • shit:Python GUI is Shit。
    • PyQT:PyQT 纵有千般好,GPL 协议拖住了
  • pygame:高可移植性的游戏开发模块
  • panda3D:一个 3D 渲染和游戏开发库
  • turtle:有意思的图形绘制函数库。

概述

  • 结论:Python GUI is Shit. 需要界面功能的情况请走 web。
  • 过于凋零,PyQT 协议问题不好应用于商业环境,wxPython、Tk 不太能打。
  • Robin Dunn 用 Python 语言对 wxWidgets 做了一层封装,封装后便成了 Python 版 GUI 库 wxPython;
  • wxGlade-0.9.4 不好用,丑
  • Frame(外围轮廓),Sizer(内部控件区)menubar(顶部菜单栏),statusBar(底部状态栏)
  • 终端界面:
    • click:命令行,重点在参数,OUT
    • 特性:任意嵌套命令 + 自动生成帮助页面 + 支持在运 1 行时延迟加载子命令
    • colorama:在控制台、命令行输出彩色文字的模块,功能简单,OUT
    • rich:终端美化库
    • cliff:创建多级命令,OUT
    • prompt-toolkit:上面有个 nubia 更易用,OUT
    • nubia:没有合适的文档,Released: Dec 16, 2020,OUT
    • pyside6:开发较复杂,维护较复杂
    • streamlit:web,运行复杂,源码放出
    • 命令行界面:界面 low,开发
    • clint:着色、缩行、列打印、进度条

GUI:图形用户界面:Graphical User Interface:在计算机屏幕上显示信息

  • 渲染:将内存中的内容输出到屏幕上。

GUI 设计

主要由两部分组成

  • 视觉设计:传达产品的外观和感觉
  • 交互设计:元素的功能和逻辑组织

人机界面 (HMI) 是一种用户界面,允许人类操作员与机器或过程进行交互。HMI 通常用于工业环境,允许操作员监视和控制过程,例如工厂或发电厂中的过程。

HMI 可以采用多种形式,包括计算机上的图形用户界面 (GUI)、触摸屏或带有按钮和显示器的物理控制面板。它们用于向操作员呈现过程数据,允许操作员输入命令和设定值,以及提供警报和其他信息。

人机界面的类型

图形界面(Graphical User Interface,简称 GUI):这些是基于计算机的 HMI,使用图形界面来显示过程数据并允许操作员输入命令。GUI 可以使用 Microsoft Windows 等软件或专门的 HMI 软件包创建。
触摸界面(Touchscreen Interface):通过触摸屏幕进行交互,具有简单、直观的交互方式,常用于智能手机、平板电脑、交互式白板等设备上。
语音界面(Voice Interface):通过语音识别技术进行交互,用户可以通过语音指令控制计算机,常用于智能音箱、车载系统等设备上。
物理面板:这些是物理 HMI,使用按钮,开关和显示器来显示过程数据并允许操作员输入命令。通常用于 GUI 或触摸屏可能不实用的工业环境,例如振动或灰尘水平较高的环境。
基于 Web 的界面:这些人机界面使用 Web 浏览器来呈现过程数据并允许操作员输入命令。它们可以通过 Web 浏览器从任何设备访问,允许操作员远程监视和控制过程。

人机界面的选择

在为工业过程或系统选择人机界面 (HMI) 时,需要考虑几个因素,以确保 HMI 最适合特定应用。

兼容性: 选择与其将要控制的设备和系统兼容的 HMI 非常重要。这包括与控制系统、通信协议和设备使用的数据格式的兼容性。

硬件: HMI 应设计为坚固耐用,适合安装环境。它应该能够承受它将要承受的温度、湿度和振动。

显示: HMI 应具有清晰、易于阅读且易于导航的显示屏。屏幕应具有良好的分辨率,具有高质量的显示和背光。

可用性: HMI 应易于操作和理解,具有直观的导航和清晰简洁的显示。它具有不同专业知识水平的操作员应该易于使用和理解。

数据可视化: HMI 应该能够以清晰有意义的方式显示数据,使用图形、图表和其他类型的可视化表示来帮助操作员了解流程并做出明智的决策。

可定制性: HMI 应该是可定制的,能够适应过程或设备的特定需求,以及操作员的偏好。

远程访问: HMI 应设计为允许远程访问,以便操作员可以从远程位置监视和控制过程。

可扩展性: HMI 应设计为可扩展,随着流程或设备变得更加先进,能够处理更多的复杂性和数据。

支持: HMI 供应商应提供良好的技术支持和文档,以及软件更新和升级。

人机界面 (HMI) 具有几个优点,可用于控制和监控工业过程:

  • **提高效率:**HMI 允许操作员轻松访问过程数据和输入命令,从而提高被控制过程的效率。通过以清晰简洁的方式呈现数据,运营商可以做出更明智的决策,并在必要时及时采取行动。
  • **提高安全性:**HMI 可以通过向操作员显示警报和其他重要信息来提高安全性。这使运营商能够及时采取行动,在潜在问题变得严重之前解决它们。
  • **远程监测和控制:**许多 HMI 可以远程访问,允许操作员从远处监视和控制过程。这在过程位于偏远或危险位置的应用中特别有用。
  • **易于使用:**HMI 设计为易于使用,即使对于可能没有技术专长的操作员也是如此。这使它们成为控制和监控工业过程的可访问工具。

terminal_layout

terminal_layout:命令行 UI 布局工具

  • 官方文档
  • 特点:
  • 核心概念:
    • LayoutCtl:layout 管理器,负责绘制所有元素
    • View:基础控件:width, visibility,gravity
      • Layout:布局控制器,控制 TextView 显示的位置
        • TableLayout:表格布局
        • TableRow:行布局
    • TextView:用于显示文字的 view
      - text,back,style,fore,weight

基本使用

1
pip install terminal-layout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
from terminal_layout import *

ctl = LayoutCtl.quick(
TableLayout,
[
[TextView('title', 'Student', fore=Fore.black, back=Back.blue, width=17, gravity=Gravity.center)],
[TextView('', 'No.', width=5, back=Back.blue), TextView('', 'Name', width=12, back=Back.blue)],
[TextView('st1_no', '1', width=5, back=Back.blue), TextView('st1_name', 'Bob', width=12, back=Back.blue)],
[TextView('st2_no', '2', width=5, back=Back.blue), TextView('st2_name', 'Tom', width=12, back=Back.blue)],
],
)

ctl.draw()
ctl.stop()

LayoutCtl

  • 传入参数为 View
1
2
3
4
ctl = LayoutCtl(TextView('title', 'Title', width=10, back=Back.blue))
ctl = LayoutCtl(row)
ctl.draw()
ctl.stop()
1
tl.TableLayout('id',width=tl.Width.fill)
1
2
3
TableRow('id')
TableRow.quick_init('row1', [TextView('title', 'Title', width=Width.wrap)], width=20,
gravity=Gravity.center)
1
tl.TextView('teext1','hello',fore=Fore.red)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
from terminal_layout import *

row1 = TableRow.quick_init('row1', [TextView('title', 'Title', width=Width.wrap)], width=10,
gravity=Gravity.center)

data1_view = TextView('data1', '1.', width=3)
data2_view = TextView('data2', 'foo', width=5)
row2 = TableRow.quick_init('row2', [data1_view, data2_view])

table_layout = TableLayout.quick_init('', [row1, row2], width=10)

ctl = LayoutCtl(table_layout)
ctl.draw()
ctl.stop()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class View

__init__(id, # view的唯一ID
width, # 宽度,正整数或Width.wrap, Width.fill
height=1, # view的高度,固定为1
visibility=Visibility.visible, # 是否显示:Visibility.visible,Visibility.invisible,Visibility.gone
gravity=Gravity.left) # 内部对齐方式:Gravity.left,Gravity.center,Gravity.right

# 获取初始化时设置的width
def get_width()

# 最终显示的宽度
def get_real_width()

# 向view中添加一个view
add_view(view)

# 向view中每个位置插入一个view
insert(index, view)

TableLayout

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class TableLayout:
__init__( # gravit总是为left
id,
width=Width.fill,
height=1,
visibility=Visibility.visible
)


classmethod quick_init(id,
data, # 初始的view list
width=Width.fill,
height=1,
visibility=Visibility.visible)

def add_view(view):
def add_view_list(view_list):

TableRow

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class TableLayout:
__init__(id,
width=Width.fill,
height=1,
back=None, # 背景色
visibility=Visibility.visible,
gravity=Gravity.left)
def quict_init(id,
data, # 初始的view list
width=Width.fill,
height=1,
back=None,
visibility=Visibility.visible,
gravity=Gravity.left
)

# 向view中添加一个view,只支持添加TextView
def add_view(view):

# 向view中添加多个view,只支持添加TextView
def add_view_list(view_list):

TextView

1
2
3
4
5
6
7
8
9
10
11
12
class TextView:
__init__(id,
text, # 文本内容
fore=None, # 文本颜色
back=None, # 背景色
style=None, # 字体样式
width=Width.wrap, # 宽度比重
height=1, # 高度
weight=None,
visibility=Visibility.visible,
gravity=Gravity.left):
pass

键盘按键

Tkinter

Tkinter:【标准库】Python 的标总体来说 Tk GUI 工具包的接口,Tk8.0 的后续版本可以实现本地窗口风格,并良好地运行在绝大多数平台中。

  • 制作古董级 GUI 的库,调用操作系统提供的本地 GUI 接口,完成最终的 GUI。
  • 工具:
    • Tkinter-Designer-1.0.4:laji,还以为像宣传的一样好,运行 python gui.py 后的登录帐号字体未显示全,界面有种莫名的违和感,generate 时弹出的 Windows 经典风的弹窗,弃了弃了
      • 以及那文档…写得不能说乱七八糟,也称得上让人摸不着头脑(我只是想初步尝试下,愣是踩了几个坑,比如.exe 是没有的、链接是跳转不过去的)
      • 2022-01-08:1.6.3:有所提升了,but,还是差点意思,作者还是挺拼的,程序有点我的风格,这满满的 Typora 导出用户手册风,这界面设计感
        • 看函数手册,def 的函数名是驼峰的?不能忍,手册为什么代码是一行一行,不是代码块?不能忍
        • 主题,白色的时候,窗体边缘没了,不能忍
        • 运行实例项目,缺少了一个库,它自动弹出了 cmd,给我装上了这个库?这太自作主张了吧,OUT
        • 还是转 QT 了,啃 pyside6 吧
    • TKinterDesigner-v1.6.7-win64.rar:依旧不好用,垃圾
    • tkinter:tk 主题小部件
    • tkinter.tix:Extension widgets for Tk
    • tkinter.scrolledtext:滚动文字控件

基本使用

1
2
3
import tkinter
root = tkinter.TK() #生成主窗口
root.mainloop() #进入消息循环
1
2
3
4
5
6
7
8
9
import tkinter as tk

app = tk.Tk()
app.title("测试程序")
label_msg = tk.Label(app, text="This is a Label")
label_msg.pack()
# 进入无限循环
app.mainloop()

组件

0- 组件公有属性

  • Dimension:控件大小
  • Color:颜色
  • Font:字体
  • Anchor:锚点
  • Relief:样式
  • Bitmap:位图
  • Cursor:光标
1
2
3
tkFont.families()
# 前景色、背景色
labelExample1 = tk.Label(app, text="Customized Color",bg="gray", fg="red")

几何状态管理方法

  • pack():包装
  • grid():网格
  • place():位置

按钮 -Button

画布 -Canvas

  • 显法图形元素如线条或文本

多选框 -Checkbutton

输入 Entry

  • 显示简单的文本内容

框架 -Frame

  • 显示一个矩形区域,多用来作为容器

标签 -Label

  • 显示文本和位图
1
2
3
4
5
6
7
8
9
10
11
12
tk.Label(app, text="Customized Label 1", font=("Times", 20,'italic'))

labelFont3 = tkFont.Font(family="Helvetica", size=20, weight=tkFont.BOLD,
underline=1, overstrike=1)
labelExample3 = tk.Label(app, text="Customized Label 3",
font=labelFont3)

# 图片
logo = tk.PhotoImage(file='python.gif')
labelExample = tk.Label(app, image=logo)
labelExample.pack()
app.mainloop()

列表框 -Listbox

  • 显示字符串列表给用户

菜单按钮 -Menubutton

  • 显示菜单项

菜单 -Menu

  • 显示菜单栏、下拉菜单和弹出菜单

消息 -Message

  • 显示比行文本

单选 -Radiobutton

  • 单选按钮

范围 -Scale

  • 显示一个数值刻度,为输出限定范围的数字区间

滚动条 -Scrollbar

  • 当内容超过可视化区域时使用,如列表框

文本 -Text

  • 显示多行文本

容器 -Toplevel

  • 用来提供一个单独的对话框,与 Frame 比较类似

输入 -Spinbox

  • 与 Entry 类似,但可指定输入范围值

窗口布局 -PanedWindow

  • 可包含一个或多个子控件

容器 -LabelFrame

  • 常用于复杂的窗口布局

应用程序消息框 -tkMessageBox

  • 添加组件
    • 按钮
      文本框
      框架
      菜单
      单选框
1
2
3
4
5
6
7
8
9
10
11
12
13
14
import tkinter
import turtle
root = tkinter.TK() #生成主窗口
label = tkinter.Label(root,text="你好") # 生成标签
label.pack() #标签添加到主窗口
button1 = tkinter.Button(root,text="五角星") # 生成按钮
button1.pack() #将按钮添加至主窗口
#事件响应函数
def wjx(event):
for i in range(5):
turtle.forward(100)
turtle.right(144)
button1.bind('<Button-1>',wjx) #绑定事件
root.mainloop() #进入消息循环
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
import tkinter as tk


window=tk.Tk()
window.title('MyWindow')
window.geometry('800x600')


# 文字标签
label1 = tk.Label(window,
text='OMG! this is TK!', # 标签的文字
# bg='green', # 背景颜色
font=('Arial', 12), # 字体和字体大小
width=15, height=2 # 标签长宽
)
label1.pack() # 固定窗口位置


var = tk.StringVar() # 这时文字变量储存器
label2 = tk.Label(window,
textvariable=var, # 使用 textvariable 替换 text, 因为这个可以变化
bg='red', font=('Arial', 12), width=15, height=2)
label2.pack()


on_hit = False # 默认初始状态为 False
def hit_me():
global on_hit
if on_hit == False: # 从 False 状态变成 True 状态
on_hit = True
var.set('you hit me') # 设置标签的文字为 'you hit me'
else: # 从 True 状态变成 False 状态
on_hit = False
var.set('') # 设置 文字为空

button1 = tk.Button(window,
text='hit me', # 显示在按钮上的文字
width=15, height=2,
command=hit_me ) # 点击按钮式执行的命令

def insert_point():
var = e.get()
t.insert('insert',var)

def insert_end():
var = e.get()
t.insert('end',var)
button1.pack() # 按钮位置
b1 = tk.Button(window,text="insert point",width=15,height=2,command=insert_point)
b1.pack()

b2 = tk.Button(window,text="insert end",command=insert_end)
b2.pack()

e = tk.Entry(window,show='*')
e.pack()

t = tk.Text(window,height=2)
t.pack()

window.mainloop()

Shit

shit:Python GUI is Shit。F**King GUI,**,

PyQT:PyQT 纵有千般好,GPL 协议拖住了
TK:制作古董级 GUI 的库。
wxPython:不太行
PyGTK:不行
PySide:说是比较慢

  • 碎片化收集的文字懒得整理了,Shit
  • F**king Shit!年月日,工作有做界面开发需求:
    • Pyside6(pyqt 的可商用版):好复杂,难以快速上手,说是文档很多,没找到合适的文档,官方的文档也理不清
    • tk、wxpython、pygtk:这些,有个说法是,有些东西,你看到它的时候,它就已经是过时的了,更别提去学它了
    • kivy:不好用,文档的核心部分太随意(一堆内容在讲安装?)

wxpython

wxpython:跨平台的 C++ 编写的 LGPL 协议的,文档少的,代码布局控件不直观的 GUI 框架

  • 将 wxWidgets 跨平台 GUI 库从其原生 C ++ 引入 Python
  • wxFormBuilder
1
2
3
4
5
import wx
app = wx.App() # 应用程序对象
frame = wx.Frame(parent= None) #框架窗口对象
frame.Show() #显示框架窗口
app.MainLoop() #进入消息循环

pygtk

pygtk:windows 下兼容有问题,弃

pygame

pygame:高可移植性的游戏开发模块

  • pykyra
  • pyweek

panda3D

panda3D:一个 3D 渲染和游戏开发库

turtle

turtle:有意思的图形绘制函数库。

  • turtle 海龟走过的轨迹绘制成了图形。

rich

rich:不错的终端显示工具,在终端中提供富文本格式和精美的格式的模块

  • 特点:
    • 富文本与漂亮的格式
    • 表情符号
    • 表格
    • 进度条
    • 标记
    • 语法高亮
    • markdown
  • 参考资料
  • 因在 windows 的 cmd.exe 显示效果不好 且 当前未有直接的需求(streamlit 牛*),先 mark,后续有需求了再掌握。

基本使用

1
pip install rich

urwid

urwid:Linux、OSX、Cygwin 或其他类 unix 操作系统上 Python 的控制台用户界面库,部分支持 Windows 操作系统

pystray

  • 托盘图标
给博主来一杯卡布奇诺