使用wxPython开发FGCC数据库查看器的完整指南
作者:winfredzhang
在企业级应用开发中,Forguncy是一款流行的低代码开发平台,然而,在实际工作中,开发人员经常面临以下痛点:数据检查困难、操作繁琐等问题,所以本文给大家介绍了使用wxPython开发FGCC数据库查看器的完整指南,需要的朋友可以参考下
一、背景
1.1 问题的提出
在企业级应用开发中,Forguncy是一款流行的低代码开发平台。它将应用程序打包为.fgcc格式的文件,这种文件本质上是一个ZIP压缩包,内部包含了应用的各种资源,其中最重要的是ForguncyDB.sqlite3数据库文件。
然而,在实际工作中,开发人员经常面临以下痛点:
C:\pythoncode\new\fgcc_db_viewer.py
- 数据检查困难:无法直接查看FGCC文件中的数据库内容
- 操作繁琐:需要手动解压、查找数据库文件、使用第三方工具打开
- 效率低下:频繁的数据库检查工作耗费大量时间
- 工具分散:需要在多个软件之间切换(解压工具、数据库查看器等)
1.2 技术选型
为了解决这些问题,我们选择了以下技术栈:
- wxPython:成熟的跨平台GUI框架,提供原生外观
- SQLite3:Python内置模块,无需额外安装
- zipfile:Python标准库,处理ZIP格式文件
二、目标
2.1 核心功能需求
我们要开发一个集成化的工具,实现以下功能:
- 文件选择:通过图形界面选择FGCC文件
- 自动解析:自动提取ZIP中的数据库文件
- 数据库连接:自动连接SQLite数据库
- 表结构展示:列出所有数据库表名
- 数据查看:双击表名即可查看完整数据
- 数据导出:支持将数据库文件导出到指定位置
2.2 用户体验目标
- 一站式操作:所有功能在一个窗口完成
- 直观易用:符合用户操作习惯的界面设计
- 实时反馈:每个操作都有状态提示
- 错误处理:友好的错误提示和异常处理

三、方法
3.1 架构设计
采用单窗口多面板的设计模式:
┌─────────────────────────────────────────┐ │ 文件选择区 [选择] [导出] │ ├──────────────┬──────────────────────────┤ │ 表列表面板 │ 数据展示面板 │ │ (ListBox) │ (Grid) │ │ │ │ │ - Table1 │ Col1 Col2 Col3 │ │ - Table2 │ data data data │ │ - Table3 │ data data data │ └──────────────┴──────────────────────────┘ │ 状态栏 │ └─────────────────────────────────────────┘
3.2 核心技术方案
文件处理流程:
- 用户选择
.fgcc文件 - 使用
zipfile模块打开ZIP文件 - 搜索并提取
ForguncyDB.sqlite3 - 保存到临时目录
- 建立SQLite连接
数据展示方案:
- 使用
wx.ListBox展示表名列表 - 使用
wx.grid.Grid展示表数据 - 通过
wx.SplitterWindow实现可调整的分割布局
四、实现过程
4.1 项目初始化
首先导入必要的模块:
import wx import wx.grid import zipfile import sqlite3 import os import tempfile from pathlib import Path
这里需要特别注意:wx.grid必须单独导入,否则会出现AttributeError错误。
4.2 主窗口框架构建
创建继承自wx.Frame的主窗口类:
class DatabaseViewerFrame(wx.Frame):
def __init__(self):
super().__init__(parent=None, title='FGCC数据库查看器',
size=(1000, 600))
self.db_path = None # 数据库文件路径
self.conn = None # 数据库连接对象
self.temp_dir = tempfile.mkdtemp() # 临时目录
self.init_ui()
self.Bind(wx.EVT_CLOSE, self.on_close)
self.Centre()
self.Show()
设计要点:
- 使用临时目录存储提取的数据库文件
- 绑定关闭事件以确保资源清理
Centre()方法使窗口居中显示
4.3 用户界面构建
4.3.1 文件选择区域
file_sizer = wx.BoxSizer(wx.HORIZONTAL) self.file_text = wx.TextCtrl(panel, style=wx.TE_READONLY) select_btn = wx.Button(panel, label='选择FGCC文件') select_btn.Bind(wx.EVT_BUTTON, self.on_select_file) self.export_btn = wx.Button(panel, label='导出数据库') self.export_btn.Enable(False) # 初始禁用 self.export_btn.Bind(wx.EVT_BUTTON, self.on_export_database)
关键技术:
wx.TE_READONLY:文本框只读,防止手动修改Enable(False):按钮初始禁用,加载数据库后才启用- 使用
BoxSizer实现水平布局
4.3.2 分割窗口设计
splitter = wx.SplitterWindow(panel) # 左侧面板:表列表 left_panel = wx.Panel(splitter) self.table_list = wx.ListBox(left_panel) self.table_list.Bind(wx.EVT_LISTBOX_DCLICK, self.on_table_double_click) # 右侧面板:数据网格 right_panel = wx.Panel(splitter) self.data_grid = wx.grid.Grid(right_panel) self.data_grid.CreateGrid(0, 0) self.data_grid.EnableEditing(False) # 设置分割比例 splitter.SplitVertically(left_panel, right_panel) splitter.SetSashPosition(250) splitter.SetMinimumPaneSize(200)
亮点设计:
SplitterWindow允许用户拖动调整左右面板大小- 左侧面板固定250像素宽度,但可调整
- 数据网格禁用编辑,保护数据安全
- 双击事件绑定实现直观的交互
4.4 核心功能实现
4.4.1 文件选择与解析
def on_select_file(self, event):
with wx.FileDialog(self, "选择FGCC文件",
wildcard="FGCC files (*.fgcc)|*.fgcc",
style=wx.FD_OPEN | wx.FD_FILE_MUST_EXIST) as dlg:
if dlg.ShowModal() == wx.ID_OK:
fgcc_path = dlg.GetPath()
self.file_text.SetValue(fgcc_path)
self.extract_and_connect(fgcc_path)
技术细节:
- 使用上下文管理器自动管理对话框资源
wildcard参数过滤文件类型wx.FD_FILE_MUST_EXIST确保文件存在
4.4.2 ZIP文件提取
def extract_and_connect(self, fgcc_path):
try:
# 关闭之前的连接
if self.conn:
self.conn.close()
self.status_bar.SetStatusText('正在提取数据库文件...')
with zipfile.ZipFile(fgcc_path, 'r') as zip_ref:
# 智能查找数据库文件
db_file = None
for name in zip_ref.namelist():
if 'ForguncyDB.sqlite3' in name:
db_file = name
break
if not db_file:
wx.MessageBox('未找到ForguncyDB.sqlite3文件',
'错误', wx.OK | wx.ICON_ERROR)
return
# 提取到临时目录
zip_ref.extract(db_file, self.temp_dir)
self.db_path = os.path.join(self.temp_dir, db_file)
# 连接数据库
self.conn = sqlite3.connect(self.db_path)
self.load_tables()
self.export_btn.Enable(True)
except Exception as e:
wx.MessageBox(f'处理文件时出错: {str(e)}',
'错误', wx.OK | wx.ICON_ERROR)
关键实现:
- 遍历ZIP文件列表查找目标文件(支持不同路径结构)
- 使用临时目录避免污染用户文件系统
- 完善的异常处理和用户提示
- 成功后启用导出按钮
4.4.3 数据库表加载
def load_tables(self):
try:
cursor = self.conn.cursor()
cursor.execute(
"SELECT name FROM sqlite_master WHERE type='table' ORDER BY name"
)
tables = cursor.fetchall()
self.table_list.Clear()
for table in tables:
self.table_list.Append(table[0])
# 清空数据网格
if self.data_grid.GetNumberRows() > 0:
self.data_grid.DeleteRows(0, self.data_grid.GetNumberRows())
if self.data_grid.GetNumberCols() > 0:
self.data_grid.DeleteCols(0, self.data_grid.GetNumberCols())
except Exception as e:
wx.MessageBox(f'加载表列表时出错: {str(e)}',
'错误', wx.OK | wx.ICON_ERROR)
SQL技巧:
- 查询
sqlite_master系统表获取所有表名 WHERE type='table'过滤掉视图和索引ORDER BY name按字母顺序排序
4.4.4 表数据动态展示
def load_table_data(self, table_name):
try:
cursor = self.conn.cursor()
cursor.execute(f'SELECT * FROM "{table_name}"')
rows = cursor.fetchall()
columns = [description[0] for description in cursor.description]
# 动态创建网格
if self.data_grid.GetNumberRows() > 0:
self.data_grid.DeleteRows(0, self.data_grid.GetNumberRows())
if self.data_grid.GetNumberCols() > 0:
self.data_grid.DeleteCols(0, self.data_grid.GetNumberCols())
# 设置列
if len(columns) > 0:
self.data_grid.AppendCols(len(columns))
for i, col in enumerate(columns):
self.data_grid.SetColLabelValue(i, col)
# 填充数据
if len(rows) > 0:
self.data_grid.AppendRows(len(rows))
for i, row in enumerate(rows):
for j, value in enumerate(row):
self.data_grid.SetCellValue(
i, j, str(value) if value is not None else ''
)
# 自动调整列宽
self.data_grid.AutoSizeColumns()
self.data_label.SetLabel(
f'记录数据: {table_name} (共 {len(rows)} 条记录)'
)
except Exception as e:
wx.MessageBox(f'加载表数据时出错: {str(e)}',
'错误', wx.OK | wx.ICON_ERROR)
实现亮点:
- 使用双引号包裹表名,支持包含特殊字符的表名
- 通过
cursor.description获取列名 - 动态创建网格,适应不同表结构
AutoSizeColumns()智能调整列宽- NULL值显示为空字符串,提升可读性
4.4.5 数据库导出功能
def on_export_database(self, event):
if not self.db_path or not os.path.exists(self.db_path):
wx.MessageBox('没有可导出的数据库文件',
'错误', wx.OK | wx.ICON_ERROR)
return
with wx.FileDialog(self, "导出数据库文件",
defaultFile="ForguncyDB.sqlite3",
wildcard="SQLite database (*.sqlite3)|*.sqlite3|All files (*.*)|*.*",
style=wx.FD_SAVE | wx.FD_OVERWRITE_PROMPT) as dlg:
if dlg.ShowModal() == wx.ID_OK:
export_path = dlg.GetPath()
try:
import shutil
shutil.copy2(self.db_path, export_path)
wx.MessageBox(f'数据库已成功导出到:\n{export_path}',
'成功', wx.OK | wx.ICON_INFORMATION)
except Exception as e:
wx.MessageBox(f'导出数据库时出错: {str(e)}',
'错误', wx.OK | wx.ICON_ERROR)
设计考虑:
wx.FD_OVERWRITE_PROMPT自动提示覆盖确认shutil.copy2保留文件元数据- 导出成功后显示完整路径,方便用户定位
4.4.6 资源清理
def on_close(self, event):
# 关闭数据库连接
if self.conn:
self.conn.close()
# 删除临时文件
try:
import shutil
if os.path.exists(self.temp_dir):
shutil.rmtree(self.temp_dir)
except:
pass
self.Destroy()
最佳实践:
- 程序退出前清理所有资源
- 删除临时文件避免磁盘占用
- 使用
try-except确保即使清理失败也能正常退出
五、运行结果
5.1 程序启动界面
启动程序后,呈现简洁的主界面:
- 顶部显示文件选择区域
- 导出按钮处于禁用状态
- 左右分割面板为空
- 状态栏提示"请选择FGCC文件"
5.2 加载FGCC文件
点击"选择FGCC文件"按钮后:
- 弹出文件选择对话框,过滤
.fgcc格式 - 选择文件后自动开始解析
- 状态栏显示"正在提取数据库文件…"
- 成功后状态栏显示"数据库加载成功"
- 左侧面板列出所有数据库表名
- "导出数据库"按钮变为可用状态
5.3 查看表数据
双击任意表名:
- 右侧网格自动填充该表的所有数据
- 列标题显示字段名
- 数据按行展示,支持滚动查看
- 列宽自动调整适应内容
- 标题栏显示表名和记录总数
5.4 导出数据库
点击"导出数据库"按钮:
- 弹出保存对话框,默认文件名为
ForguncyDB.sqlite3 - 选择保存位置并确认
- 如文件已存在,提示是否覆盖
- 导出成功后显示完整保存路径
- 状态栏更新显示导出信息
以上就是使用wxPython开发FGCC数据库查看器的完整指南的详细内容,更多关于wxPython FGCC数据库查看器的资料请关注脚本之家其它相关文章!
