当前位置:首页>python>Python Tkinter工业监控界面总是乱成一团?试试MVC这剂良药

Python Tkinter工业监控界面总是乱成一团?试试MVC这剂良药

  • 2026-02-25 23:05:56
Python Tkinter工业监控界面总是乱成一团?试试MVC这剂良药

去年帮一家电气厂做界面重构,第一次看到他们的代码时我人都傻了——一个.py文件里塞了2800多行。按钮点击事件里直接写串口通信,数据处理逻辑和UI更新代码缠在一起,像缠成死结的电线团。老工程师苦笑:"改个显示格式要翻半天,生怕碰坏了PLC通信。"这场景,你是不是也遇到过?

工业软件不比互联网应用——设备一旦上线,运维成本高到离谱。但偏偏很多工控界面还停留在"能跑就行"的阶段,代码维护全凭记忆力。今天咱们就聊聊如何用MVC模式把Tkinter工业界面从"屎山"改造成可维护、可扩展的工程级代码。读完这篇,你能拿走一套直接能用的架构模板,让你的监控系统代码量减少40%的同时,维护效率翻倍。

🔍 为什么工业界面这么容易写乱?

真正的痛点在这儿

多数人觉得"界面就是画几个按钮嘛",实际上工业场景复杂得多:

  • • 数据源五花八门:Modbus设备、PLC、传感器、数据库历史记录...每种协议都不一样
  • • 实时性要求高:温度超限得立刻变红闪烁,延迟200ms都可能误事
  • • 界面状态复杂:同一个阀门按钮,手动模式能点,自动模式得禁用,故障时还要显示不同颜色

当你把这些需求用"想到哪写到哪"的方式堆起来,结果就是:

# 某真实项目的噩梦代码(简化版)
defon_start_button_click():
ifself.mode == "manual":
self.status_label.config(text="启动中", fg="yellow")
        ser.write(b'\x01\x05\x00\x00\xFF\x00')  # 直接写串口命令
        time.sleep(0.1)
        response = ser.read(8)
if response[1] == 0x05:
self.status_label.config(text="运行", fg="green")
self.db.execute("INSERT INTO logs...")  # 又插数据库
self.chart.add_point(...)  # 还更新图表

你看——一个按钮回调函数里,硬件通信、界面更新、数据库操作全混在一起。改通信协议要动UI代码,换个显示颜色又得小心避开通信逻辑。这不叫开发,这叫拆弹。

常见的三大误区

  1. 1. "工业软件简单,不需要设计模式"——等你第三次在凌晨接到"改个显示BUG"的电话就懂了
  2. 2. "MVC太重了,Tkinter小项目用不着"——其实300行代码就能建立清晰架构
  3. 3. "反正就我一人维护"——三个月后的你就是另一个人,读自己代码一样头大

🏗️ MVC到底是什么玩意儿?

别被那些学术定义吓到。简单说,MVC就是把代码分成三个"工人":

角色
职责
工业场景类比
Model(模型)
管数据和业务逻辑
像PLC控制器,只负责执行指令和存状态
View(视图)
管界面显示
像HMI屏幕,只负责显示,不管数据哪来的
Controller(控制器)
协调两者
像调度员,接到操作指令后决定谁干啥

关键好处?改一个不影响另外俩。换个ModbusTCP改成485?只动Model。客户要把按钮从圆的改成方的?只动View。

💡 实战架构:一个完整的温控监控系统

咱们来写个真实场景——锅炉温度监控界面。功能简单但五脏俱全:

  • • 实时显示温度曲线
  • • 设置温度阈值
  • • 超限报警
  • • 手动/自动模式切换

第一步:搭建Model(数据大脑)

import random
import threading
import time

classBoilerModel:
"""锅炉数据模型 - 不关心界面长啥样"""

def__init__(self):
self.temperature = 25.0# 当前温度
self.threshold = 80.0# 报警阈值
self.is_running = False
self.mode = "manual"# manual/auto
self._observers = []     # 观察者列表(谁关心数据变化)

defadd_observer(self, callback):
"""注册观察者 - View通过这个监听数据变化"""
self._observers.append(callback)

defnotify_observers(self):
"""数据变了,通知所有观察者"""
for callback inself._observers:
            callback(self.get_status())

defget_status(self):
"""获取当前状态(给View用的)"""
return {
'temperature'self.temperature,
'threshold'self.threshold,
'is_alarm'self.temperature > self.threshold,
'mode'self.mode,
'is_running'self.is_running
        }

defset_threshold(self, value):
"""业务逻辑:设置阈值"""
if0 < value < 200:  # 合法性检查
self.threshold = value
self.notify_observers()
returnTrue
returnFalse

defstart_monitoring(self):
"""模拟实时采集温度(实际项目这里是串口/Modbus通信)"""
self.is_running = True

defsimulate_sensor():
whileself.is_running:
# 真实项目这里替换成:ser.read() 或 modbus_client.read_holding_registers()
self.temperature += random.uniform(-23)
self.temperature = max(20min(120self.temperature))
self.notify_observers()
                time.sleep(0.5)

        threading.Thread(target=simulate_sensor, daemon=True).start()

defstop_monitoring(self):
self.is_running = False
self.notify_observers()

关键设计点

  • • 🎯 观察者模式:View不需要主动查询,数据变化时Model会推送
  • • 🔒 ��据验证set_threshold里做边界检查,防止非法输入
  • • 🧵 线程隔离:数据采集用独立线程,不卡界面

第二步:构建View层(只管好看)

import tkinter as tk  
from tkinter import ttk, messagebox  
from matplotlib.figure import Figure  
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg  
import matplotlib  

# 设置字体为支持中文的字体  
matplotlib.rcParams['font.sans-serif'] = ['Microsoft YaHei']  # 微软雅黑  
matplotlib.rcParams['axes.unicode_minus'] = False# 解决负号显示问题  

classBoilerView:  
"""纯UI层 - 不知道数据哪来的,只负责显示"""

def__init__(self, root):  
self.root = root  
self.root.title("锅炉温控系统 v2.0")  
self.root.geometry("800x600")  

# 存储最近100个温度点(用于绘图)  
self.temp_history = []  

self._create_widgets()  

def_create_widgets(self):  
"""搭建界面结构"""

# ===== 顶部状态栏 =====        status_frame = tk.Frame(self.root, bg="
#34495e", height=60)  
        status_frame.pack(fill=tk.X)  

        tk.Label(  
            status_frame,  
            text="当前温度:",  
            bg="#34495e",  
            fg="white",  
            font=("微软雅黑"12)  
        ).pack(side=tk.LEFT, padx=20, pady=15)  

self.temp_label = tk.Label(  
            status_frame,  
            text="-- °C",  
            bg="#34495e",  
            fg="#2ecc71",  
            font=("微软雅黑"24)  
        )  
self.temp_label.pack(side=tk.LEFT)  

self.alarm_label = tk.Label(  
            status_frame,  
            text="●",  
            bg="#34495e",  
            fg="#95a5a6",  
            font=("微软雅黑"36)  
        )  
self.alarm_label.pack(side=tk.RIGHT, padx=20)  

# ===== 中部图表区 =====        chart_frame = tk.Frame(self.root)  
        chart_frame.pack(fill=tk.BOTH, expand=True, padx=10, pady=10)  

self.figure = Figure(figsize=(84), dpi=100)  
self.ax = self.figure.add_subplot(111)  
self.ax.set_title("温度曲线", fontsize=14)  
self.ax.set_xlabel("时间序列")  
self.ax.set_ylabel("温度 (°C)")  
self.ax.grid(True, alpha=0.3)  

self.canvas = FigureCanvasTkAgg(self.figure, chart_frame)  
self.canvas.get_tk_widget().pack(fill=tk.BOTH, expand=True)  

# ===== 底部控制区 =====        control_frame = tk.Frame(self.root, bg="#ecf0f1", height=100)  
        control_frame.pack(fill=tk.X, side=tk.BOTTOM)  

        tk.Label(  
            control_frame,  
            text="报警阈值:",  
            bg="#ecf0f1",  
            font=("微软雅黑"10)  
        ).grid(row=0, column=0, padx=20, pady=10)  

self.threshold_entry = tk.Entry(control_frame, width=10, font=("Arial"12))  
self.threshold_entry.grid(row=0, column=1)  

self.set_threshold_btn = tk.Button(  
            control_frame,  
            text="设置阈值",  
            bg="#3498db",  
            fg="white",  
            font=("微软雅黑"10),  
            cursor="hand2"
        )  
self.set_threshold_btn.grid(row=0, column=2, padx=10)  

self.start_btn = tk.Button(  
            control_frame,  
            text="▶ 开始监控",  
            bg="#2ecc71",  
            fg="white",  
            font=("微软雅黑"11"bold"),  
            width=12,  
            cursor="hand2"
        )  
self.start_btn.grid(row=0, column=3, padx=10)  

self.stop_btn = tk.Button(  
            control_frame,  
            text="■ 停止",  
            bg="#e74c3c",  
            fg="white",  
            font=("微软雅黑"11"bold"),  
            width=12,  
            cursor="hand2",  
            state=tk.DISABLED  
        )  
self.stop_btn.grid(row=0, column=4)  

defupdate_display(self, status):  
"""更新界面显示(Controller调用这个方法)"""
        temp = status['temperature']  
        is_alarm = status['is_alarm']  

# 更新温度显示  
self.temp_label.config(  
            text=f"{temp:.1f} °C",  
            fg="#e74c3c"if is_alarm else"#2ecc71"
        )  

# 更新报警指示灯  
self.alarm_label.config(  
            fg="#e74c3c"if is_alarm else"#95a5a6"
        )  

# 更新曲线  
self.temp_history.append(temp)  
iflen(self.temp_history) > 100:  
self.temp_history.pop(0)  

self.ax.clear()  
self.ax.plot(self.temp_history, color="#3498db", linewidth=2)  
self.ax.axhline(  
            y=status['threshold'],  
            color="#e74c3c",  
            linestyle="--",  
            label=f"阈值 {status['threshold']}°C"
        )  
self.ax.legend()  
self.ax.grid(True, alpha=0.3)  
self.canvas.draw()  

# 更新按钮状态  
if status['is_running']:  
self.start_btn.config(state=tk.DISABLED)  
self.stop_btn.config(state=tk.NORMAL)  
else:  
self.start_btn.config(state=tk.NORMAL)  
self.stop_btn.config(state=tk.DISABLED)  

defshow_error(self, message):  
"""显示错误提示"""
        messagebox.showerror("错误", message)  

defget_threshold_input(self):  
"""获取用户输入的阈值"""
returnself.threshold_entry.get()

看到没?View里没有任何业务逻辑。它就像个传声筒:

  • • 对外暴露update_display()接收数据
  • • 对外暴露get_threshold_input()提供输入
  • • 按钮点击事件稍后绑定给Controller

第三步:Controller层(交通警察)


classBoilerController:
"""控制器 - 协调Model和View"""

def__init__(self, model, view):
self.model = model
self.view = view

# 绑定View的按钮事件
self.view.start_btn.config(command=self.on_start)
self.view.stop_btn.config(command=self.on_stop)
self.view.set_threshold_btn.config(command=self.on_set_threshold)

# 让Model的数据变化通知View更新
self.model.add_observer(self.on_model_changed)

# 初始化显示
self.on_model_changed(self.model.get_status())

defon_start(self):
"""用户点了"开始监控"按钮"""
self.model.start_monitoring()

defon_stop(self):
"""用户点了"停止"按钮"""
self.model.stop_monitoring()

defon_set_threshold(self):
"""用户要设置阈值"""
try:
            value = float(self.view.get_threshold_input())
ifnotself.model.set_threshold(value):
self.view.show_error("阈值范围必须在 0-200°C 之间")
except ValueError:
self.view.show_error("请输入有效的数字")

defon_model_changed(self, status):
"""Model数据变化时的回调"""
self.view.update_display(status)

Controller超级简洁——它就做两件事:

  1. 1. 把View的用户操作转发给Model
  2. 2. 把Model的数据变化转发给View

第四步:主程序入口

# main.py
import tkinter as tk  
from BoilerController import BoilerController  
from BoilerModel import BoilerModel  
from BoilerView import BoilerView  


if __name__ == "__main__":  
    root = tk.Tk()  

# 组装MVC三件套  
    model = BoilerModel()  
    view = BoilerView(root)  
    controller = BoilerController(model, view)  

    root.mainloop()


就四行核心代码!干净得像刚擦过的玻璃。

🚀 实战效果对比

我拿这套架构重构了开头提到的那个项目,对比数据很惊艳:

指标
重构前
重构后
提升
单文件代码行数
2800+
最大380行
-87%
修改显示样式耗时
40分钟
5分钟
8倍
切换通信协议耗时
半天
1小时
4倍
新人上手周期
1周
2天
--

真实场景收益

  • • 后来客户要加第二个设备监控,我直接复用Model层,20分钟搞定
  • • UI设计师改了三版界面方案,我只改View文件,Model代码一行没动
  • • 从Modbus RTU换成Modbus TCP,只改了BoilerModel里8行代码

⚠️ 别踩这些坑

坑1:View里偷偷写业务逻辑

# ❌ 错误示范
defon_button_click(self):
    temp = float(self.temp_entry.get())
if temp > 100:  # 这是业务逻辑,不该在View里!
self.model.set_alarm()

正确做法:View只负责获取输入,判断逻辑扔给Model。

坑2:Model直接操作Tkinter组件

# ❌ 千万别这么干
classMyModel:
defupdate_data(self):
self.label.config(text="新数据")  # Model不该知道Label的存在!

一旦Model知道了View的存在,你的架构就白搭了。

坑3:忘记在主线程更新UI

Tkinter有个铁律:UI更新必须在主线程。如果你的Model用线程采集数据,要这样通知View:

defnotify_observers(self):
for callback inself._observers:
# 用after确保回调在主线程执行
self.root.after(0lambda: callback(self.get_status()))

🎁 可直接复用的模板

把上面的代码稍作调整,你能复用到这些场景:

  1. 1. 电机监控:Model换成电机转速/电流数据,View换成仪表盘
  2. 2. 传送带控制:Model加个速度控制接口,View加个滑块
  3. 3. 多设备巡检:Model改成列表存多个设备,View用树形控件展示

核心不变:Model管数据,View管显示,Controller协调。

💬 来聊聊你的场景

留言区说说:

  1. 1. 你现在的工业项目代码结构是啥样?
  2. 2. 遇到过"改一处影响全局"的惨案吗?
  3. 3. 如果让你用MVC重构现有项目,最大障碍是什么?

点赞最高的问题,我下期文章专门解答!

🎯 三个核心外卖

读到这儿,把这三句话截图保存:

金句1:工业软件的复杂度不在功能,在维护。MVC让你写完六个月后还能看懂自己的代码。

金句2:Model管"是什么",View管"长什么样",Controller管"怎么办"——职责分明,各司其职。

金句3:好的架构不是一次写对,而是让你有底气随时重构。

📚 进阶学习路线

掌握今天的内容后,你可以继续探索:

  1. 1. 状态机模式:处理复杂的设备状态切换(手动/自动/故障/维护)
  2. 2. 命令模式:实现操作历史记录和撤销功能
  3. 3. 工厂模式:优雅地管理不同类型的传感器对象
  4. 4. 配置文件驱动:用JSON/YAML配置界面布局,实现零代码换皮肤

下一期咱们聊**《Tkinter + SQLite:工业数据本地存储的七个最佳实践》**,包括高频写入优化、断电数据保护、历史曲线快速查询。关注公众号别错过!


标签#Python工控#Tkinter实战#MVC设计模式#工业软件开发#代码重构


如果这篇文章帮你理清了思路,点个"在看"让更多做工控的朋友看到。代码写得清爽,下班回家才爽快! 🍺

最新文章

随机文章

基本 文件 流程 错误 SQL 调试
  1. 请求信息 : 2026-02-28 12:43:14 HTTP/2.0 GET : https://f.mffb.com.cn/a/476431.html
  2. 运行时间 : 0.168662s [ 吞吐率:5.93req/s ] 内存消耗:4,411.79kb 文件加载:140
  3. 缓存信息 : 0 reads,0 writes
  4. 会话信息 : SESSION_ID=5a9d93a8d92699dbb2f297e77a6692ea
  1. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/public/index.php ( 0.79 KB )
  2. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/autoload.php ( 0.17 KB )
  3. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/autoload_real.php ( 2.49 KB )
  4. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/platform_check.php ( 0.90 KB )
  5. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/ClassLoader.php ( 14.03 KB )
  6. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/autoload_static.php ( 4.90 KB )
  7. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/helper.php ( 8.34 KB )
  8. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-validate/src/helper.php ( 2.19 KB )
  9. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/helper.php ( 1.47 KB )
  10. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/stubs/load_stubs.php ( 0.16 KB )
  11. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Exception.php ( 1.69 KB )
  12. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-container/src/Facade.php ( 2.71 KB )
  13. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/deprecation-contracts/function.php ( 0.99 KB )
  14. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/polyfill-mbstring/bootstrap.php ( 8.26 KB )
  15. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/polyfill-mbstring/bootstrap80.php ( 9.78 KB )
  16. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/var-dumper/Resources/functions/dump.php ( 1.49 KB )
  17. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-dumper/src/helper.php ( 0.18 KB )
  18. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/var-dumper/VarDumper.php ( 4.30 KB )
  19. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/App.php ( 15.30 KB )
  20. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-container/src/Container.php ( 15.76 KB )
  21. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/container/src/ContainerInterface.php ( 1.02 KB )
  22. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/provider.php ( 0.19 KB )
  23. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Http.php ( 6.04 KB )
  24. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/helper/Str.php ( 7.29 KB )
  25. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Env.php ( 4.68 KB )
  26. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/common.php ( 0.03 KB )
  27. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/helper.php ( 18.78 KB )
  28. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Config.php ( 5.54 KB )
  29. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/app.php ( 0.95 KB )
  30. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/cache.php ( 0.78 KB )
  31. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/console.php ( 0.23 KB )
  32. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/cookie.php ( 0.56 KB )
  33. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/database.php ( 2.48 KB )
  34. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/facade/Env.php ( 1.67 KB )
  35. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/filesystem.php ( 0.61 KB )
  36. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/lang.php ( 0.91 KB )
  37. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/log.php ( 1.35 KB )
  38. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/middleware.php ( 0.19 KB )
  39. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/route.php ( 1.89 KB )
  40. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/session.php ( 0.57 KB )
  41. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/trace.php ( 0.34 KB )
  42. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/view.php ( 0.82 KB )
  43. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/event.php ( 0.25 KB )
  44. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Event.php ( 7.67 KB )
  45. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/service.php ( 0.13 KB )
  46. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/AppService.php ( 0.26 KB )
  47. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Service.php ( 1.64 KB )
  48. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Lang.php ( 7.35 KB )
  49. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/lang/zh-cn.php ( 13.70 KB )
  50. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/initializer/Error.php ( 3.31 KB )
  51. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/initializer/RegisterService.php ( 1.33 KB )
  52. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/services.php ( 0.14 KB )
  53. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/service/PaginatorService.php ( 1.52 KB )
  54. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/service/ValidateService.php ( 0.99 KB )
  55. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/service/ModelService.php ( 2.04 KB )
  56. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-trace/src/Service.php ( 0.77 KB )
  57. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Middleware.php ( 6.72 KB )
  58. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/initializer/BootService.php ( 0.77 KB )
  59. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/Paginator.php ( 11.86 KB )
  60. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-validate/src/Validate.php ( 63.20 KB )
  61. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/Model.php ( 23.55 KB )
  62. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/Attribute.php ( 21.05 KB )
  63. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/AutoWriteData.php ( 4.21 KB )
  64. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/Conversion.php ( 6.44 KB )
  65. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/DbConnect.php ( 5.16 KB )
  66. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/ModelEvent.php ( 2.33 KB )
  67. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/RelationShip.php ( 28.29 KB )
  68. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/contract/Arrayable.php ( 0.09 KB )
  69. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/contract/Jsonable.php ( 0.13 KB )
  70. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/contract/Modelable.php ( 0.09 KB )
  71. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Db.php ( 2.88 KB )
  72. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/DbManager.php ( 8.52 KB )
  73. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Log.php ( 6.28 KB )
  74. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Manager.php ( 3.92 KB )
  75. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/log/src/LoggerTrait.php ( 2.69 KB )
  76. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/log/src/LoggerInterface.php ( 2.71 KB )
  77. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Cache.php ( 4.92 KB )
  78. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/simple-cache/src/CacheInterface.php ( 4.71 KB )
  79. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/helper/Arr.php ( 16.63 KB )
  80. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/cache/driver/File.php ( 7.84 KB )
  81. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/cache/Driver.php ( 9.03 KB )
  82. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/CacheHandlerInterface.php ( 1.99 KB )
  83. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/Request.php ( 0.09 KB )
  84. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Request.php ( 55.78 KB )
  85. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/middleware.php ( 0.25 KB )
  86. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Pipeline.php ( 2.61 KB )
  87. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-trace/src/TraceDebug.php ( 3.40 KB )
  88. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/middleware/SessionInit.php ( 1.94 KB )
  89. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Session.php ( 1.80 KB )
  90. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/session/driver/File.php ( 6.27 KB )
  91. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/SessionHandlerInterface.php ( 0.87 KB )
  92. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/session/Store.php ( 7.12 KB )
  93. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Route.php ( 23.73 KB )
  94. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/RuleName.php ( 5.75 KB )
  95. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/Domain.php ( 2.53 KB )
  96. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/RuleGroup.php ( 22.43 KB )
  97. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/Rule.php ( 26.95 KB )
  98. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/RuleItem.php ( 9.78 KB )
  99. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/route/app.php ( 1.72 KB )
  100. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/facade/Route.php ( 4.70 KB )
  101. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/dispatch/Controller.php ( 4.74 KB )
  102. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/Dispatch.php ( 10.44 KB )
  103. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/controller/Index.php ( 4.81 KB )
  104. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/BaseController.php ( 2.05 KB )
  105. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/facade/Db.php ( 0.93 KB )
  106. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/connector/Mysql.php ( 5.44 KB )
  107. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/PDOConnection.php ( 52.47 KB )
  108. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/Connection.php ( 8.39 KB )
  109. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/ConnectionInterface.php ( 4.57 KB )
  110. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/builder/Mysql.php ( 16.58 KB )
  111. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/Builder.php ( 24.06 KB )
  112. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/BaseBuilder.php ( 27.50 KB )
  113. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/Query.php ( 15.71 KB )
  114. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/BaseQuery.php ( 45.13 KB )
  115. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/TimeFieldQuery.php ( 7.43 KB )
  116. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/AggregateQuery.php ( 3.26 KB )
  117. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/ModelRelationQuery.php ( 20.07 KB )
  118. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/ParamsBind.php ( 3.66 KB )
  119. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/ResultOperation.php ( 7.01 KB )
  120. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/WhereQuery.php ( 19.37 KB )
  121. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/JoinAndViewQuery.php ( 7.11 KB )
  122. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/TableFieldInfo.php ( 2.63 KB )
  123. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/Transaction.php ( 2.77 KB )
  124. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/log/driver/File.php ( 5.96 KB )
  125. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/LogHandlerInterface.php ( 0.86 KB )
  126. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/log/Channel.php ( 3.89 KB )
  127. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/event/LogRecord.php ( 1.02 KB )
  128. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/Collection.php ( 16.47 KB )
  129. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/facade/View.php ( 1.70 KB )
  130. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/View.php ( 4.39 KB )
  131. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Response.php ( 8.81 KB )
  132. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/response/View.php ( 3.29 KB )
  133. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Cookie.php ( 6.06 KB )
  134. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-view/src/Think.php ( 8.38 KB )
  135. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/TemplateHandlerInterface.php ( 1.60 KB )
  136. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-template/src/Template.php ( 46.61 KB )
  137. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-template/src/template/driver/File.php ( 2.41 KB )
  138. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-template/src/template/contract/DriverInterface.php ( 0.86 KB )
  139. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/runtime/temp/067d451b9a0c665040f3f1bdd3293d68.php ( 11.98 KB )
  140. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-trace/src/Html.php ( 4.42 KB )
  1. CONNECT:[ UseTime:0.000627s ] mysql:host=127.0.0.1;port=3306;dbname=f_mffb;charset=utf8mb4
  2. SHOW FULL COLUMNS FROM `fenlei` [ RunTime:0.000685s ]
  3. SELECT * FROM `fenlei` WHERE `fid` = 0 [ RunTime:0.011584s ]
  4. SELECT * FROM `fenlei` WHERE `fid` = 63 [ RunTime:0.001034s ]
  5. SHOW FULL COLUMNS FROM `set` [ RunTime:0.000668s ]
  6. SELECT * FROM `set` [ RunTime:0.001278s ]
  7. SHOW FULL COLUMNS FROM `article` [ RunTime:0.000880s ]
  8. SELECT * FROM `article` WHERE `id` = 476431 LIMIT 1 [ RunTime:0.003091s ]
  9. UPDATE `article` SET `lasttime` = 1772253794 WHERE `id` = 476431 [ RunTime:0.013901s ]
  10. SELECT * FROM `fenlei` WHERE `id` = 66 LIMIT 1 [ RunTime:0.000574s ]
  11. SELECT * FROM `article` WHERE `id` < 476431 ORDER BY `id` DESC LIMIT 1 [ RunTime:0.001625s ]
  12. SELECT * FROM `article` WHERE `id` > 476431 ORDER BY `id` ASC LIMIT 1 [ RunTime:0.008935s ]
  13. SELECT * FROM `article` WHERE `id` < 476431 ORDER BY `id` DESC LIMIT 10 [ RunTime:0.008857s ]
  14. SELECT * FROM `article` WHERE `id` < 476431 ORDER BY `id` DESC LIMIT 10,10 [ RunTime:0.016397s ]
  15. SELECT * FROM `article` WHERE `id` < 476431 ORDER BY `id` DESC LIMIT 20,10 [ RunTime:0.005953s ]
0.170353s