文章目录
- 在企业级应用开发中,Forguncy是一款流行的低代码开发平台。它将应用程序打包为.fgcc格式的文件,这种文件本质上是一个ZIP压缩包,内部包含了应用的各种资源,其中最重要的是ForguncyDB.sqlite3数据库文件。 然而,在实际工作中,开发人员经常面临以下痛点:C:pythoncodenewfgcc_db_viewer.py 数据检查困难:无法直接查看FGCC文件中的数据库内容 操作繁琐:需要手动解压、查找数据库文件、使用第三方工具打开 效率低下:频繁的数据库检查工作耗费大量时间 工具分散:需要在多个软件之间切换(解压工具、数据库查看器等)
- 为了解决这些问题,我们选择了以下技术栈: wxPython:成熟的跨平台GUI框架,提供原生外观 SQLite3:Python内置模块,无需额外安装 zipfile:Python标准库,处理ZIP格式文件
- 采用单窗口多面板的设计模式: ┌─────────────────────────────────────────┐ │ 文件选择区 [选择] [导出] │ ├──────────────┬──────────────────────────┤ │ 表列表面板 │ 数据展示面板 │ │ (ListBox) │ (Grid) │ │ │ │ │ – Table1 │ Col1 Col2 Col3 │ │ – Table2 │ data data data │ │ – Table3 │ data data data │ └──────────────┴──────────────────────────┘ │ 状态栏 │ └─────────────────────────────────────────┘
- 文件处理流程: 用户选择.fgcc文件 使用zipfile模块打开ZIP文件 搜索并提取ForguncyDB.sqlite3 保存到临时目录 建立SQLite连接 数据展示方案: 使用wx.ListBox展示表名列表 使用wx.grid.Grid展示表数据 通过wx.SplitterWindow实现可调整的分割布局
- 首先导入必要的模块: import wx import wx.grid import zipfile import sqlite3 import os import tempfile from pathlib import Path 这里需要特别注意:wx.grid必须单独导入,否则会出现AttributeError错误。
- 创建继承自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()方法使窗口居中显示
-
- 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实现水平布局
- 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像素宽度,但可调整 数据网格禁用编辑,保护数据安全 双击事件绑定实现直观的交互
-
- 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确保文件存在
- 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文件列表查找目标文件(支持不同路径结构) 使用临时目录避免污染用户文件系统 完善的异常处理和用户提示 成功后启用导出按钮
- 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按字母顺序排序
- 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值显示为空字符串,提升可读性
- 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保留文件元数据 导出成功后显示完整路径,方便用户定位
- 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确保即使清理失败也能正常退出
- 启动程序后,呈现简洁的主界面: 顶部显示文件选择区域 导出按钮处于禁用状态 左右分割面板为空 状态栏提示"请选择FGCC文件"
- 点击"选择FGCC文件"按钮后: 弹出文件选择对话框,过滤.fgcc格式 选择文件后自动开始解析 状态栏显示"正在提取数据库文件…" 成功后状态栏显示"数据库加载成功" 左侧面板列出所有数据库表名 "导出数据库"按钮变为可用状态
- 双击任意表名: 右侧网格自动填充该表的所有数据 列标题显示字段名 数据按行展示,支持滚动查看 列宽自动调整适应内容 标题栏显示表名和记录总数
- 点击"导出数据库"按钮: 弹出保存对话框,默认文件名为ForguncyDB.sqlite3 选择保存位置并确认 如文件已存在,提示是否覆盖 导出成功后显示完整保存路径 状态栏更新显示导出信息 以上就是使用wxPython开发FGCC数据库查看器的完整指南的详细内容,更多关于wxPython FGCC数据库查看器的资料请关注风君子博客其它相关文章! 您可能感兴趣的文章: 基于wxPython和DeepSeek API开发的智能批处理文件生成器 Python使用wxPython开发电脑信息二维码生成器 Python结合wxPython打造一个优雅的图片预览工具 基于Python和wxPython打造一个智能日期文件夹管理工具 Python结合wxPython与PyMuPDF手搓一个PDF编辑器
目录
- 一、背景
- 1.1 问题的提出
- 1.2 技术选型
- 二、目标
- 2.1 核心功能需求
- 2.2 用户体验目标
- 三、方法
- 3.1 架构设计
- 3.2 核心技术方案
- 四、实现过程
- 4.1 项目初始化
- 4.2 主窗口框架构建
- 4.3 用户界面构建
- 4.3.1 文件选择区域
- 4.3.2 分割窗口设计
- 4.4 核心功能实现
- 4.4.1 文件选择与解析
- 4.4.2 ZIP文件提取
- 4.4.3 数据库表加载
- 4.4.4 表数据动态展示
- 4.4.5 数据库导出功能
- 4.4.6 资源清理
- 五、运行结果
- 5.1 程序启动界面
- 5.2 加载FGCC文件
- 5.3 查看表数据
- 5.4 导出数据库
在企业级应用开发中,Forguncy是一款流行的低代码开发平台。它将应用程序打包为.fgcc格式的文件,这种文件本质上是一个ZIP压缩包,内部包含了应用的各种资源,其中最重要的是ForguncyDB.sqlite3数据库文件。
然而,在实际工作中,开发人员经常面临以下痛点:
C:pythoncodenewfgcc_db_viewer.py
- 数据检查困难:无法直接查看FGCC文件中的数据库内容
- 操作繁琐:需要手动解压、查找数据库文件、使用第三方工具打开
- 效率低下:频繁的数据库检查工作耗费大量时间
- 工具分散:需要在多个软件之间切换(解压工具、数据库查看器等)
为了解决这些问题,我们选择了以下技术栈:
- wxPython:成熟的跨平台GUI框架,提供原生外观
- SQLite3:Python内置模块,无需额外安装
- zipfile:Python标准库,处理ZIP格式文件
我们要开发一个集成化的工具,实现以下功能:
- 文件选择:通过图形界面选择FGCC文件
- 自动解析:自动提取ZIP中的数据库文件
- 数据库连接:自动连接SQLite数据库
- 表结构展示:列出所有数据库表名
- 数据查看:双击表名即可查看完整数据
- 数据导出:支持将数据库文件导出到指定位置
- 一站式操作:所有功能在一个窗口完成
- 直观易用:符合用户操作习惯的界面设计
- 实时反馈:每个操作都有状态提示
- 错误处理:友好的错误提示和异常处理

采用单窗口多面板的设计模式:
┌─────────────────────────────────────────┐ │ 文件选择区 [选择] [导出] │ ├──────────────┬──────────────────────────┤ │ 表列表面板 │ 数据展示面板 │ │ (ListBox) │ (Grid) │ │ │ │ │ - Table1 │ Col1 Col2 Col3 │ │ - Table2 │ data data data │ │ - Table3 │ data data data │ └──────────────┴──────────────────────────┘ │ 状态栏 │ └─────────────────────────────────────────┘
文件处理流程:
- 用户选择
.fgcc文件 - 使用
zipfile模块打开ZIP文件 - 搜索并提取
ForguncyDB.sqlite3 - 保存到临时目录
- 建立SQLite连接
数据展示方案:
- 使用
wx.ListBox展示表名列表 - 使用
wx.grid.Grid展示表数据 - 通过
wx.SplitterWindow实现可调整的分割布局
首先导入必要的模块:
import wx import wx.grid import zipfile import sqlite3 import os import tempfile from pathlib import Path
这里需要特别注意:wx.grid必须单独导入,否则会出现AttributeError错误。
创建继承自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()方法使窗口居中显示
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实现水平布局
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像素宽度,但可调整
- 数据网格禁用编辑,保护数据安全
- 双击事件绑定实现直观的交互
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确保文件存在
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文件列表查找目标文件(支持不同路径结构)
- 使用临时目录避免污染用户文件系统
- 完善的异常处理和用户提示
- 成功后启用导出按钮
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按字母顺序排序
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值显示为空字符串,提升可读性
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保留文件元数据- 导出成功后显示完整路径,方便用户定位
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确保即使清理失败也能正常退出
启动程序后,呈现简洁的主界面:
- 顶部显示文件选择区域
- 导出按钮处于禁用状态
- 左右分割面板为空
- 状态栏提示"请选择FGCC文件"
点击"选择FGCC文件"按钮后:
- 弹出文件选择对话框,过滤
.fgcc格式 - 选择文件后自动开始解析
- 状态栏显示"正在提取数据库文件…"
- 成功后状态栏显示"数据库加载成功"
- 左侧面板列出所有数据库表名
- "导出数据库"按钮变为可用状态
双击任意表名:
- 右侧网格自动填充该表的所有数据
- 列标题显示字段名
- 数据按行展示,支持滚动查看
- 列宽自动调整适应内容
- 标题栏显示表名和记录总数
点击"导出数据库"按钮:
- 弹出保存对话框,默认文件名为
ForguncyDB.sqlite3 - 选择保存位置并确认
- 如文件已存在,提示是否覆盖
- 导出成功后显示完整保存路径
- 状态栏更新显示导出信息
以上就是使用wxPython开发FGCC数据库查看器的完整指南的详细内容,更多关于wxPython FGCC数据库查看器的资料请关注风君子博客其它相关文章!
您可能感兴趣的文章:
- 基于wxPython和DeepSeek API开发的智能批处理文件生成器
- Python使用wxPython开发电脑信息二维码生成器
- Python结合wxPython打造一个优雅的图片预览工具
- 基于Python和wxPython打造一个智能日期文件夹管理工具
- Python结合wxPython与PyMuPDF手搓一个PDF编辑器