Python的UI
Tkinter
- Python的标准GUI工具包,由Python内置,支持大多数Unix、Windows、Mac
- 文档:https://docs.python.org/zh-cn/3.13/library/tkinter.html
- 将python的tcl8.6和tk8.6文件夹放到python的lib文件夹下
- pack布局
import tkinter as tk # pack 简单自动排列,适合线性布局 root = tk.Tk() root.geometry('500x500') # side布局方向top,bottom,left,right # fill控制组件填充方式tk.X,tk.Y,tk.BOTH,None # padx:水平方向外边距pady,垂直方向外边距ipadx,水平方向内边距ipady,垂直方向内边距 # expand是否扩展填充额外空间(布尔值) # anchor组件在分配空间内的对齐方式(N, S, E, W, CENTER等) # 主框架 main_frame = tk.Frame(root) main_frame.pack(expand=True, fill=tk.BOTH, padx=10, pady=10) # 左侧面板 left_panel = tk.Frame(main_frame, bg="lightgray") left_panel.pack(side=tk.LEFT, fill=tk.Y, padx=(0, 10)) # 右侧面板 right_panel = tk.Frame(main_frame) right_panel.pack(side=tk.RIGHT, expand=True, fill=tk.BOTH) # 在左侧面板添加组件 tk.Label(left_panel, text="导航菜单", bg="lightgray").pack(pady=5) tk.Button(left_panel, text="选项1").pack(fill=tk.X) tk.Button(left_panel, text="选项2").pack(fill=tk.X) # 在右侧面板添加组件 tk.Label(right_panel, text="内容区域").pack(anchor=tk.NW) tk.Text(right_panel).pack(expand=True, fill=tk.BOTH) root.mainloop()
- place布局
import tkinter as tk # place相对于窗口的绝对定位 root = tk.Tk() root.title("title") root.geometry('500x500') # relx,rely相对父组件的位置0最左边,1最右边 # width,height组件长宽 # relwidth,relheight相对父组件的长宽0-1 # anchor对齐方式n,s,w,e,center(默认) tk.Label(root, text='Hello World').place(relx=0.4,rely=0.4,x=0, y=0) tk.Button(root, text='Quit', command=root.quit).place(relx=0.4,rely=0.4,x=0, y=100,height=40,width=80) root.mainloop()
- grid布局(字符串转MD5)
from tkinter import * import hashlib import time LOG_LINE_NUM = 0 class MY_GUI(): def __init__(self,init_window_name): self.init_window_name = init_window_name #设置窗口 def set_init_window(self): self.init_window_name.title("文本处理工具_v1.2") #窗口名 #self.init_window_name.geometry('320x160+10+10') #290 160为窗口大小,+10 +10 定义窗口弹出时的默认展示位置 self.init_window_name.geometry('1068x681+100+100') #self.init_window_name["bg"] = "pink" #窗口背景色,其他背景色见:blog.csdn.net/chl0000/article/details/7657887 #self.init_window_name.attributes("-alpha",0.9) #虚化,值越小虚化程度越高 #标签 self.init_data_label = Label(self.init_window_name, text="待处理数据") self.init_data_label.grid(row=0, column=0) self.result_data_label = Label(self.init_window_name, text="输出结果") self.result_data_label.grid(row=0, column=12) self.log_label = Label(self.init_window_name, text="日志") self.log_label.grid(row=12, column=0) #文本框 self.init_data_Text = Text(self.init_window_name, width=67, height=35) #原始数据录入框 self.init_data_Text.grid(row=1, column=0, rowspan=10, columnspan=10) self.result_data_Text = Text(self.init_window_name, width=70, height=49) #处理结果展示 self.result_data_Text.grid(row=1, column=12, rowspan=15, columnspan=10) self.log_data_Text = Text(self.init_window_name, width=66, height=9) # 日志框 self.log_data_Text.grid(row=13, column=0, columnspan=10) #按钮 self.str_trans_to_md5_button = Button(self.init_window_name, text="字符串转MD5", bg="lightblue", width=10,command=self.str_trans_to_md5) # 调用内部方法 加()为直接调用 self.str_trans_to_md5_button.grid(row=1, column=11) #功能函数 def str_trans_to_md5(self): src = self.init_data_Text.get(1.0,END).strip().replace("\n","").encode() #print("src =",src) if src: try: myMd5 = hashlib.md5() myMd5.update(src) myMd5_Digest = myMd5.hexdigest() #print(myMd5_Digest) #输出到界面 self.result_data_Text.delete(1.0,END) self.result_data_Text.insert(1.0,myMd5_Digest) self.write_log_to_Text("INFO:str_trans_to_md5 success") except: self.result_data_Text.delete(1.0,END) self.result_data_Text.insert(1.0,"字符串转MD5失败") else: self.write_log_to_Text("ERROR:str_trans_to_md5 failed") #获取当前时间 def get_current_time(self): current_time = time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time())) return current_time #日志动态打印 def write_log_to_Text(self,logmsg): global LOG_LINE_NUM current_time = self.get_current_time() logmsg_in = str(current_time) +" " + str(logmsg) + "\n" #换行 if LOG_LINE_NUM <= 7: self.log_data_Text.insert(END, logmsg_in) LOG_LINE_NUM = LOG_LINE_NUM + 1 else: self.log_data_Text.delete(1.0,2.0) self.log_data_Text.insert(END, logmsg_in) def gui_start(): init_window = Tk() ZMJ_PORTAL = MY_GUI(init_window) # 设置根窗口默认属性 ZMJ_PORTAL.set_init_window() init_window.mainloop() gui_start()
PyQt5
基于强大的Qt库,Qt是一个跨平台的C++框架。支持Windows、macOS、Linux
demo
from PyQt5.QtWidgets import QApplication, QPushButton, QLabel, QVBoxLayout, QWidget def on_button_click(): label.setText("Hello, PyQt!") app = QApplication([]) window = QWidget() layout = QVBoxLayout() button = QPushButton("Click Me") button.clicked.connect(on_button_click) layout.addWidget(button) label = QLabel("Waiting for click...") layout.addWidget(label) window.setLayout(layout) window.show() app.exec_()
QWidget: 所有控件(按钮、标签等)的基类。任何可视化控件基本上都可以继承自QWidget。最基础的窗口控件,可以创建简单的窗口。
QMainWindow: 高级窗口控件,继承QWidget,具有更多功能,如菜单栏、工具栏、状态栏
QVBoxLayout垂直布局
import sys from PyQt5.QtWidgets import QApplication, QMainWindow, QWidget, QVBoxLayout, QHBoxLayout, QPushButton, QLabel class MainWindow(QMainWindow): def __init__(self): super().__init__() self.setWindowTitle("PyQt5 布局示例") # 设置窗口标题 # 创建主窗口中的中央控件,QMainWindow 需要设置中央控件 central_widget = QWidget(self) self.setCentralWidget(central_widget) # 创建垂直布局管理器 vbox_layout = QVBoxLayout() # 创建标签控件并添加到布局中 label = QLabel("这是一个标签") vbox_layout.addWidget(label) # 创建两个按钮,并添加到水平布局中 button1 = QPushButton("按钮 1") button2 = QPushButton("按钮 2") vbox_layout.addWidget(button1) vbox_layout.addWidget(button2) central_widget.setLayout(vbox_layout) app = QApplication(sys.argv) window = MainWindow() window.show() sys.exit(app.exec_())
QHBoxLayout水平布局
import sys from PyQt5.QtWidgets import QApplication, QMainWindow, QWidget, QVBoxLayout, QHBoxLayout, QPushButton, QLabel class MainWindow(QMainWindow): def __init__(self): super().__init__() self.setWindowTitle("PyQt5 布局示例") # 设置窗口标题 central_widget = QWidget(self) self.setCentralWidget(central_widget) label = QLabel("这是一个标签") hbox_layout = QHBoxLayout() button1 = QPushButton("按钮 1") button2 = QPushButton("按钮 2") hbox_layout.addWidget(button1) hbox_layout.addWidget(button2) hbox_layout.addWidget(label) central_widget.setLayout(hbox_layout) central_widget.setLayout(hbox_layout) app = QApplication(sys.argv) window = MainWindow() window.show() sys.exit(app.exec_())
QGridLayout网格布局
from PyQt5.QtWidgets import QApplication, QWidget, QGridLayout, QLabel, QPushButton import sys class MainWindow(QWidget): def __init__(self): super().__init__() self.setWindowTitle("QGridLayout 示例") layout = QGridLayout() layout.addWidget(QLabel("标签 1"), 0, 0) # 在第 0 行,第 0 列添加标签 layout.addWidget(QPushButton("按钮 1"), 0, 1) # 在第 0 行,第 1 列添加按钮 layout.addWidget(QLabel("标签 2"), 1, 0) # 在第 1 行,第 0 列添加标签 layout.addWidget(QPushButton("按钮 2"), 1, 1) # 在第 1 行,第 1 列添加按钮 # 将布局设置为窗口的布局 self.setLayout(layout) app = QApplication(sys.argv) window = MainWindow() window.show() sys.exit(app.exec_())
QFormLayout表单布局
from PyQt5.QtWidgets import QWidget, QFormLayout, QLineEdit, QPushButton, QApplication class LoginForm(QWidget): def __init__(self): super().__init__() layout = QFormLayout(self) # 添加标签-控件对 self.username = QLineEdit() layout.addRow("用户名:", self.username) self.password = QLineEdit(echoMode=QLineEdit.Password) layout.addRow("密码:", self.password) # 添加独占行的按钮 submit_btn = QPushButton("登录") layout.addRow(submit_btn) self.setWindowTitle("登录表单") self.resize(300, 150) app = QApplication([]) window = LoginForm() window.show() app.exec_()
打包
pip install pyinstaller
pyinstaller -F demo.py