Python写UI界面


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

参考:https://www.runoob.com/python/python-gui-tkinter.html


  目录