1.1.0版本
This commit is contained in:
126
views/collapsing_frame.py
Normal file
126
views/collapsing_frame.py
Normal file
@@ -0,0 +1,126 @@
|
||||
import ttkbootstrap as ttk
|
||||
import tkinter
|
||||
from tkinter import ttk
|
||||
from pathlib import Path
|
||||
from ttkbootstrap import Style
|
||||
import sys
|
||||
import os
|
||||
|
||||
|
||||
def get_resource_path(relative_path):
|
||||
"""
|
||||
获取资源文件的绝对路径(兼容开发环境和打包后)
|
||||
|
||||
Args:
|
||||
relative_path: 相对路径,如 "assets/icons8_double_up_24px.png"
|
||||
|
||||
Returns:
|
||||
str: 资源文件的绝对路径
|
||||
"""
|
||||
try:
|
||||
# PyInstaller 打包后的临时文件夹路径
|
||||
base_path = sys._MEIPASS
|
||||
except AttributeError:
|
||||
# 开发环境:使用项目根目录
|
||||
# 当前文件: views/collapsing_frame.py
|
||||
# 项目根目录: views 的父目录
|
||||
current_file = os.path.abspath(__file__)
|
||||
views_dir = os.path.dirname(current_file)
|
||||
base_path = os.path.dirname(views_dir)
|
||||
|
||||
return os.path.join(base_path, relative_path)
|
||||
|
||||
|
||||
class CollapsingFrame(ttk.Frame):
|
||||
"""
|
||||
A collapsible frame widget that opens and closes with a button click.
|
||||
"""
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
self.columnconfigure(0, weight=1)
|
||||
self.cumulative_rows = 0
|
||||
p = Path(__file__).parent
|
||||
self.images = [
|
||||
tkinter.PhotoImage(
|
||||
name="open", file=get_resource_path("assets/icons8_double_up_24px.png")
|
||||
),
|
||||
tkinter.PhotoImage(
|
||||
name="closed",
|
||||
file=get_resource_path("assets/icons8_double_right_24px.png"),
|
||||
),
|
||||
]
|
||||
|
||||
def add(self, child, title="", style="primary.TButton", **kwargs):
|
||||
"""Add a child to the collapsible frame
|
||||
|
||||
:param ttk.Frame child: the child frame to add to the widget
|
||||
:param str title: the title appearing on the collapsible section header
|
||||
:param str style: the ttk style to apply to the collapsible section header
|
||||
"""
|
||||
if child.winfo_class() != "TFrame": # must be a frame
|
||||
return
|
||||
style_color = style.split(".")[0]
|
||||
frm = ttk.Frame(self, style=f"{style_color}.TFrame")
|
||||
frm.grid(row=self.cumulative_rows, column=0, sticky="ew")
|
||||
|
||||
# header title
|
||||
lbl = ttk.Label(frm, text=title, style=f"{style_color}.Inverse.TLabel")
|
||||
if kwargs.get("textvariable"):
|
||||
lbl.configure(textvariable=kwargs.get("textvariable"))
|
||||
lbl.pack(side="left", fill="both", padx=10)
|
||||
|
||||
# header toggle button
|
||||
btn = ttk.Button(
|
||||
frm,
|
||||
image="open",
|
||||
style=style,
|
||||
command=lambda c=child: self._toggle_open_close(child),
|
||||
)
|
||||
btn.pack(side="right")
|
||||
|
||||
# assign toggle button to child so that it's accesible when toggling (need to change image)
|
||||
child.btn = btn
|
||||
child.grid(row=self.cumulative_rows + 1, column=0, sticky="news")
|
||||
|
||||
# increment the row assignment
|
||||
self.cumulative_rows += 2
|
||||
|
||||
def _toggle_open_close(self, child):
|
||||
"""
|
||||
Open or close the section and change the toggle button image accordingly
|
||||
|
||||
:param ttk.Frame child: the child element to add or remove from grid manager
|
||||
"""
|
||||
if child.winfo_viewable():
|
||||
child.grid_remove()
|
||||
child.btn.configure(image="closed")
|
||||
else:
|
||||
child.grid()
|
||||
child.btn.configure(image="open")
|
||||
|
||||
|
||||
# class Application(tkinter.Tk):
|
||||
|
||||
# def __init__(self):
|
||||
# super().__init__()
|
||||
# self.title('Collapsing Frame')
|
||||
# # self.style = Style()
|
||||
|
||||
# cf = CollapsingFrame(self)
|
||||
# cf.pack(fill='both')
|
||||
|
||||
# # option group 1
|
||||
# group1 = ttk.Frame(cf, padding=10)
|
||||
# for x in range(5):
|
||||
# ttk.Checkbutton(group1, text=f'Option {x + 1}').pack(fill='x')
|
||||
# cf.add(group1, title='Option Group 1', style='primary.TButton')
|
||||
|
||||
# # option group 2
|
||||
# group2 = ttk.Frame(cf, padding=10)
|
||||
# for x in range(5):
|
||||
# ttk.Checkbutton(group2, text=f'Option {x + 1}').pack(fill='x')
|
||||
# cf.add(group2, title='Option Group 2', style='danger.TButton')
|
||||
|
||||
# if __name__ == '__main__':
|
||||
# Application().mainloop()
|
||||
1230
views/pq_debug_panel.py
Normal file
1230
views/pq_debug_panel.py
Normal file
File diff suppressed because it is too large
Load Diff
31
views/pq_log_gui.py
Normal file
31
views/pq_log_gui.py
Normal file
@@ -0,0 +1,31 @@
|
||||
import tkinter as tk
|
||||
import ttkbootstrap as ttk
|
||||
|
||||
class PQLogGUI(ttk.Frame):
|
||||
def __init__(self, parent):
|
||||
super().__init__(parent)
|
||||
self.create_widgets()
|
||||
|
||||
def create_widgets(self):
|
||||
log_frame = ttk.LabelFrame(self, text="测试日志")
|
||||
log_frame.pack(fill=tk.BOTH, expand=True, padx=5, pady=5)
|
||||
|
||||
self.log_text = ttk.Text(log_frame, height=8, width=50)
|
||||
self.log_text.pack(fill=tk.BOTH, expand=True, side=tk.LEFT)
|
||||
|
||||
log_scrollbar = ttk.Scrollbar(log_frame, command=self.log_text.yview)
|
||||
log_scrollbar.pack(fill=tk.Y, side=tk.RIGHT)
|
||||
self.log_text.config(yscrollcommand=log_scrollbar.set)
|
||||
|
||||
self.log_text.config(state=tk.DISABLED)
|
||||
|
||||
def log(self, message):
|
||||
self.log_text.config(state=tk.NORMAL)
|
||||
self.log_text.insert(tk.END, message + "\n")
|
||||
self.log_text.see(tk.END)
|
||||
self.log_text.config(state=tk.DISABLED)
|
||||
|
||||
def clear_log(self):
|
||||
self.log_text.config(state=tk.NORMAL)
|
||||
self.log_text.delete(1.0, tk.END)
|
||||
self.log_text.config(state=tk.DISABLED)
|
||||
Reference in New Issue
Block a user