Py学习  »  Python

再见Tkinter!这5个Python GUI库让界面开发又变得有趣了

IT服务圈儿 • 2 周前 • 57 次点击  

1、


来源丨经授权转自 数据STUDIO
者丨云朵君
告别老旧的界面开发体验,这些现代GUI库让Python界面开发变得高效又有趣!

你是否也有过这样的经历?😫

写Python自动化脚本时一切顺利,但一到需要做个简单界面,就感觉回到了“上古时代”。Tkinter虽然经典,但它的设计风格停留在上世纪,布局管理让人抓狂,自定义样式更是难上加难。

好消息是: Python GUI生态早已今非昔比!经过一个月的探索测试,我发现了5个让界面开发既快又有趣的现代GUI库。无论你是要开发内部工具、数据看板还是客户端应用,总有一款适合你!

PyQt6:专业级GUI开发的首选

为什么选择PyQt6?

PyQt6是Qt框架的Python绑定,Qt可是Photoshop、Autodesk Maya等专业软件使用的框架!这意味着你可以用Python享受到C++级别的性能和丰富的组件库。

PyQt6

核心优势:

  • 真正的跨平台支持
  • 丰富的组件和强大的布局系统
  • 支持CSS样式的界面美化
  • 完善的信号槽机制

快速上手示例

import sys
from PyQt6.QtWidgets import (QApplication, QWidget, QLabel, 
                             QPushButton, QVBoxLayout)

# 创建应用
app = QApplication(sys.argv)

# 创建主窗口
window = QWidget()
window.setWindowTitle("PyQt6快速入门")
window.setGeometry(100100300200)  # x, y, width, height

# 创建垂直布局
layout = QVBoxLayout()

# 添加组件
label = QLabel("欢迎使用PyQt6!")
button = QPushButton("点击我")

# 连接按钮点击事件
def on_button_click():
    label.setText("按钮被点击了!")

button.clicked.connect(on_button_click)

# 将组件添加到布局
layout.addWidget(label)
layout.addWidget(button)

# 设置布局并显示窗口
window.setLayout(layout)
window.show()

# 运行应用
sys.exit(app.exec())

使用心得

  1. 学习曲线:初期需要适应信号槽机制,但一旦掌握,开发效率极高
  2. 样式美化:使用Qt Style Sheets(类似CSS)可以轻松实现现代化界面
  3. 布局管理:相比Tkinter,布局系统更加直观和强大

适合场景:专业桌面应用、需要复杂交互的企业级工具

Dear PyGui:GPU加速的轻量级GUI

与众不同的特点

Dear PyGui最大的特点是GPU加速,即使是最基础的按钮和文本渲染,也能享受硬件加速带来的流畅体验。它特别适合需要实时更新数据的监控面板和工具。

GitHub - hoffstadt/DearPyGui: Dear PyGui: A fast and powerful Graphical  User Interface Toolkit for Python with minimal dependencies

三大亮点:

  1. 基于游戏引擎的渲染架构
  2. 内置丰富的数据可视化组件
  3. 极高的性能表现

数据监控面板示例

import dearpygui.dearpygui as dpg
import random
import time

# 创建上下文
dpg.create_context()

# 模拟实时数据
def update_data():
    current_time = time.strftime("%H:%M:%S")
    cpu_usage = random.randint(2090)
    memory_usage = random.randint(3085)
    
    # 更新数据
    dpg.set_value("time_text"f"当前时间: {current_time}")
    dpg.set_value("cpu_bar", cpu_usage / 100)
    dpg.set_value("cpu_value"f"CPU: {cpu_usage}%")
    dpg.set_value("memory_bar", memory_usage / 100)
    dpg.set_value("memory_value"f"内存: {memory_usage}%")

# 创建主窗口
with dpg.window(label="系统监控面板", width=400, height=300):
    dpg.add_text("系统状态监控", color=(0200255))
    dpg.add_separator()
    
    # 时间显示
    dpg.add_text("", tag="time_text")
    
    # CPU使用率
    dpg.add_text("CPU使用情况")
    dpg.add_progress_bar(tag="cpu_bar", width=300)
    dpg.add_text("", tag="cpu_value")
    
    # 内存使用率
    dpg.add_spacing()
    dpg.add_text("内存使用情况")
    dpg.add_progress_bar(tag="memory_bar", width=300)
    dpg.add_text("", tag="memory_value")
    
    # 控制按钮
    dpg.add_spacing(count=2)
    dpg.add_button(label="开始监控", width=100)
    dpg.add_button(label="停止监控", width=100)

# 设置定时更新
dpg.set_frame_callback(10, update_data)

# 创建视口并运行
dpg.create_viewport(title='系统监控', width=420, height=350)
dpg.setup_dearpygui()
dpg.show_viewport()
dpg.start_dearpygui()
dpg.destroy_context()

使用场景推荐

  • 内部工具开发:快速搭建监控面板
  • 自动化脚本界面:为现有脚本添加可视化控制
  • 原型开发:快速验证界面设计概念

Flet:用Python写Web界面

前端开发的Python化革命

Flet让你 完全不用写JavaScript、HTML、CSS,就能创建现代化的Web应用。它基于Flutter技术,一次编写即可部署为Web应用、桌面应用和移动应用。

GitHub - flet-dev/flet: Flet enables developers to easily build realtime  web, mobile and desktop apps in Python. No frontend experience required.

核心优势:

  • 一套代码,多端运行
  • 现代化的Material Design组件
  • 响应式设计开箱即用

文件管理工具示例

import flet as ft
import os
from pathlib import Path

def main(page: ft.Page):
    page.title = "Python文件管理器"
    page.theme_mode = ft.ThemeMode.DARK  # 暗色主题
    page.padding = 20
    
    # 当前目录显示
    current_path = ft.Text(value=f"当前目录: {os.getcwd()}", size=16)
    
    # 文件列表
    file_list = ft.Column()
    
    def list_files():
        """列出当前目录文件"""
        file_list.controls.clear()
        
        # 添加返回上级目录选项
        if Path.cwd().parent != Path.cwd():
            file_list.controls.append(
                ft.ListTile(
                    leading=ft.Icon(ft.icons.FOLDER_OPEN),
                    title=ft.Text(".. (上级目录)"),
                    on_click=lambda e: change_directory(Path.cwd().parent)
                )
            )
        
        # 列出文件和目录
        for item in sorted(Path.cwd().iterdir()):
            icon = ft.icons.FOLDER if item.is_dir() else ft.icons.INSERT_DRIVE_FILE
            color = ft.colors.BLUE_200 if item.is_dir() else ft.colors.WHITE
            
            file_list.controls.append(
                ft.ListTile(
                    leading=ft.Icon(icon, color=color),
                    title=ft.Text(item.name),
                    subtitle=ft.Text(f"大小: {item.stat().st_size:,} 字节"if item.is_file() else"目录"),
                    on_click=lambda e, path=item: open_item(path)
                )
            )
        
        page.update()
    
    def change_directory(new_path):
        """切换目录"""
        os.chdir(new_path)
        current_path.value = f"当前目录: {os.getcwd()}"
        list_files()
    
    def open_item(item_path):
        """打开文件或目录"""
        if item_path.is_dir():
            change_directory(item_path)
        else:
            page.show_snack_bar(
                ft.SnackBar(ft.Text(f"打开文件: {item_path.name}"))
            )
    
    # 初始加载文件列表
    list_files()
    
    # 添加组件到页面
    page.add(
        ft.Text("Python文件管理器", size=24, weight=ft.FontWeight.BOLD),
        current_path,
        ft.Divider(),
        ft.Container(
            content=file_list,
            height=400,
            border=ft.border.all(1, ft.colors.GREY_800),
            border_radius=10,
            padding=10,
        ),
        ft.Row([
            ft.ElevatedButton("刷新", icon=ft.icons.REFRESH, on_click=lambda e: list_files()),
            ft.ElevatedButton("关于", icon=ft.icons.INFO, 
                           on_click=lambda e: page.show_dialog(
                               ft.AlertDialog(title=ft.Text("关于"),
                                           content=ft.Text("使用Flet构建的文件管理器示例"))
                           ))
        ])
    )

ft.app(target=main)

特别适合

  1. 全栈Python开发者:不想碰前端技术栈
  2. 快速原型验证:几分钟搭建可用的Web界面
  3. 内部工具分享:一键生成Web应用,团队共享使用

Textual:终端里的现代界面

为命令行工具注入灵魂

如果你的大部分工作都在终端中完成,Textual能让你在不离开终端的情况下,获得现代GUI的体验。

Textual

核心价值:

  • 保持终端工作流的完整性
  • SSH远程访问友好
  • 极低的资源占用

自动化任务管理器示例

from textual.app import App, ComposeResult
from textual.widgets import Header, Footer, Button, Static, Label
from textual.containers import Container, Horizontal, Vertical
from textual.reactive import reactive
import asyncio

class TaskManager(App):
    """任务管理器应用"""
    
    CSS = """
    Screen {
        background: $surface;
    }
    
    .task-container {
        height: 1fr;
        border: solid $primary;
        padding: 1;
    }
    
    .success {
        color: $success;
    }
    
    .error {
        color: $error;
    }
    
    .running {
        color: $warning;
    }
    """

    
    def compose(self) -> ComposeResult:
        """创建界面组件"""
        yield Header()
        
        with Container(id="main-container"):
            with Vertical(id="left-panel"):
                yield Label("自动化任务管理器", classes="title")
                yield Button("运行数据清洗", id="clean-data", variant="primary")
                yield Button("生成报告", id="generate-report", variant="success")
                yield Button("备份数据库", id="backup-db", variant="warning")
            
            with Vertical(id="right-panel", classes="task-container"):
                yield Label("任务状态", classes="subtitle")
                yield Static("", id="status-display")
        
        yield Footer()
    
    def on_button_pressed(self, event: Button.Pressed) -> None:
        """处理按钮点击事件"""
        button_id = event.button.id
        
        status_display = self.query_one("#status-display")
        
        # 模拟任务执行
        if button_id == "clean-data":
            status_display.update("[bold]正在清洗数据...[/]")
            self.run_task(self.simulate_task, "数据清洗"3)
        
        elif button_id == "generate-report":
            status_display.update("[bold]正在生成报告...[/]")
            self.run_task(self.simulate_task, "报告生成"2)
        
        elif button_id == "backup-db":
            status_display.update("[bold]正在备份数据库...[/]" )
            self.run_task(self.simulate_task, "数据库备份"4)
    
    asyncdef simulate_task(self, task_name: str, duration: int) -> None:
        """模拟长时间运行的任务"""
        status_display = self.query_one("#status-display")
        
        for i in range(duration):
            status_display.update(
                f"[bold]{task_name}进行中... ({i+1}/{duration}秒)[/]"
            )
            await asyncio.sleep(1)
        
        status_display.update(f"[bold green]✓ {task_name}完成![/]")

if __name__ == "__main__":
    app = TaskManager()
    app.run()

最佳实践场景

  • 服务器管理工具:通过SSH管理远程服务器
  • CLI工具增强:为现有命令行工具添加交互界面
  • 开发辅助工具:代码检查、测试运行等工具

CustomTkinter:Tkinter的现代化改造

让传统技术焕发新生

如果你已经有Tkinter基础,或者需要维护老项目,CustomTkinter能让你 以最小的成本获得现代化界面


核心改进:

  • 现代化的Material Design风格
  • 内置深色主题支持
  • 更合理的布局系统

现代化设置面板示例

import customtkinter as ctk
import tkinter as tk
from tkinter import messagebox

class SettingsApp:
    def __init__(self):
        # 初始化设置
        ctk.set_appearance_mode("dark")  # 深色模式
        ctk.set_default_color_theme("blue")  # 蓝色主题
        
        # 创建主窗口
        self.app = ctk.CTk()
        self.app.title("现代化设置面板")
        self.app.geometry("500x400")
        
        # 创建选项卡视图
        self.tabview = ctk.CTkTabview(self.app)
        self.tabview.pack(fill="both", expand=True, padx=20, pady=20)
        
        # 添加选项卡
        self.tabview.add("常规设置")
        self.tabview.add("外观设置")
        self.tabview.add("关于")
        
        self.setup_general_tab()
        self.setup_appearance_tab()
        self.setup_about_tab()
    
    def setup_general_tab(self):
        """设置常规选项卡"""
        tab = self.tabview.tab("常规设置")
        
         # 自动启动开关
        self.auto_start = ctk.CTkSwitch(
            tab, 
            text="开机自动启动",
            command=self.on_auto_start_change
        )
        self.auto_start.pack(pady=10, anchor="w", padx=20)
        
        # 更新检查
        self.auto_update = ctk.CTkSwitch(
            tab,
            text="自动检查更新"
        )
        self.auto_update.pack(pady=10, anchor="w", padx=20)
        
        # 日志级别选择
        ctk.CTkLabel(tab, text="日志级别:").pack(pady=(205), anchor="w", padx=20)
        
        self.log_level = ctk.CTkComboBox(
            tab,
            values=["DEBUG""INFO""WARNING""ERROR"]
        )
        self.log_level.pack(pady=5, anchor="w", padx=20, fill="x")
    
    def setup_appearance_tab(self):
        """设置外观选项卡"""
        tab = self.tabview.tab("外观设置")
        
        # 主题模式选择
        ctk.CTkLabel(tab, text="主题模式:").pack(pady=10, anchor="w", padx=20)
        
        self.theme_mode = ctk.CTkSegmentedButton(
            tab,
            values=["浅色""深色""跟随系统"],
            command=self.on_theme_change
        )
        self.theme_mode.set("深色")
        self.theme_mode.pack(pady=5, anchor="w", padx=20, fill="x")
        
        # 颜色主题
        ctk.CTkLabel(tab, text="颜色主题:").pack(pady=10, anchor="w", padx=20)
        
        self.color_theme = ctk.CTkComboBox(
            tab,
            values=["蓝色""绿色""紫色""橙色"]
        )
        self.color_theme.pack(pady=5, anchor="w", padx=20, fill="x")
    
    def setup_about_tab(self):
        """设置关于选项卡"""
        tab = self.tabview.tab("关于")
        
        # 应用信息
        info_text = """
        现代化设置面板示例
        
        版本: 1.0.0
        作者: 云朵君
        
        使用CustomTkinter构建
        提供现代化的界面体验
        """

        
        info_label = ctk.CTkLabel(tab, text=info_text, justify="left")
        info_label.pack(pady=20, padx=20)
        
        # 按钮
        button_frame = ctk.CTkFrame(tab)
        button_frame.pack(pady=20)
        
        ctk.CTkButton(
            button_frame,
            text="检查更新",
            width=100
        ).pack(side="left", padx=10)
        
        ctk.CTkButton(
            button_frame,
            text="访问官网",
            width=100
        ).pack(side="left", padx=10)
    
    def on_auto_start_change(self):
        """处理自动启动开关变化"""
        status = "开启"if self.auto_start.get() else"关闭"
        print(f"自动启动: {status}")
    
    def on_theme_change(self, value):
        """处理主题变化"""
        theme_map = {
            "浅色""light",
            "深色""dark",
            "跟随系统""system"
        }
        ctk.set_appearance_mode(theme_map[value])
        print(f"主题已切换为: {value}")
    
    def run(self):
        """运行应用"""
        self.app.mainloop()

if __name__ == "__main__":
    app = SettingsApp()
    app.run()

迁移建议

如果你正在使用Tkinter,可以:

  1. 渐进式迁移:逐步替换为CustomTkinter组件
  2. 样式统一:使用内置主题系统保持界面一致
  3. 功能增强:在保持代码结构的同时获得现代外观

写在最后

决策指南

库名称
适合场景
学习曲线
部署复杂度
美观程度
PyQt6
专业桌面应用
中等
中等
⭐⭐⭐⭐⭐
Dear PyGui
数据监控面板
简单
简单
⭐⭐⭐⭐
Flet
Web应用/多端部署
简单
简单
⭐⭐⭐⭐⭐
Textual
终端增强工具
中等
简单
⭐⭐⭐
CustomTkinter
Tkinter现代化
简单
简单
⭐⭐⭐⭐

推荐策略

  1. 要开发Web应用? → 选择 Flet
  2. 需要高性能监控面板? → 选择 Dear PyGui
  3. 开发专业桌面软件? → 选择 PyQt6
  4. 增强现有命令行工具? → 选择 Textual
  5. 现代化现有Tkinter项目? → 选择  CustomTkinter

你在Python界面开发中遇到过哪些痛点?
或者,你有哪些私藏的GUI开发技巧?

希望这篇文章能帮助你找到最适合的Python GUI开发工具!如果你有任何问题或建议,欢迎在评论区留言讨论。🚀

Happy Coding! 🎉



1、面试官问:C语言的函数指针是什么?

2、SpringSecurity、Shiro和Sa-Token,哪个更好?

3、 Go1.26 新特性:10年,Goroutine 调度指标终于来了!

4、Parrot 最新版本 7.0 发布,这次感受不同!

5、网络不通?90% 的问题靠这 7 条命令就能定位

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/191315