经过前面的装饰,软件已经有了骨架了,但是没有各类函数,只是能看、好看是没用的,还需要添加灵魂。那么接下来就是添加各类函数。
首先介绍下我这个项目,它后期需要打开时加载一些之前保存的设置内容,在之后软件有一项功能是操作EXCEL排版进行打印的,但是在打印的纸张是自定义纸张,也就是在EXCEL排版时,xlsxwriter库设置纸张时需要一个叫纸张ID的东西,一般情况下A4是9,但是自定义纸张就完全不确定了。
首先需要一个本地化的小型的数据库,这里使用的是PYTHON的tinydb库,它的本质就是一个JSON文件,不断的操作JSON来实现数据库的效果。我将tinydb封装到一个类中,方便软件后期的读写。具体tinydb怎么搞大家可以在网上找资料,很简单。直接上代码(我将它保存为名“utils_tinydb.py”:
from tinydb import TinyDB, Query, where
class Tiny_setting:
tinydb = TinyDB('setting.json') #加载JSON文件
def insert_data(self, tb_name, kv_dic): #将KV_DIC字典插入到表名TB_NAME中
table = self.tinydb.table(tb_name)
table.insert(kv_dic)
def del_data(self, tb_name, condition): #将TB_NAME中符合CONDITION条件的删除,使用方法如注释
table = self.tinydb.table(tb_name)
table.remove(condition)
# condition = Query()
# del_data('table_b', condition.age == 16)
def update_data(self, tb_name, new_dic, key=None, value=None): #将TB_NAME中符合KEY=VALUE的值更新为NEW_DIC
print(tb_name, new_dic, key, value)
table = self.tinydb.table(tb_name)
if key:
table.update(new_dic, where(key) == value)
else:
table.update(new_dic)
def search_data(self, tb_name, condition): #查找TB_NAME中符合CONDITION的结果,使用方法如注释
table = self.tinydb.table(tb_name)
data = table.search(condition)
return data
# qry = Query()
# data = search_data('table_b', qry.name=='andy')
def all_data(self, tb_name): #查找TB_NAME中所有的结果
table = self.tinydb.table(tb_name)
data = table.all()
return data
在'setting.json'中的内容是:
{"sys_setting": {"1": {"printer_id": 9}}}
代码实现如下:
tinydb_class = utils_tinydb.Tiny_setting()
boot_settings = tinydb_class.all_data(tb_name='sys_setting')
ui.input(label='打印机使用的纸张ID', value=boot_settings['printer_id'])
这段代码网上没找到,也许有更灵活的办法,但是我也没翻到。最终问了GPT,给出了如下的答案:
def get_paper_size():
# 获取默认打印机名称
default_printer = win32print.GetDefaultPrinter()
try:
# 打开打印机句柄
printer_handle = win32print.OpenPrinter(default_printer)
# 获取打印机信息
printer_info = win32print.GetPrinter(printer_handle, 2)
# 获取默认纸张ID
default_paper_id = printer_info['pDevMode'].PaperSize
return default_paper_id
except:
# 关闭打印机句柄
return 0
再编写两个用于设置INPUT结果的函数:
def update_paper_size(cls, printer_id_current): #更新软件基本设置中的打印机ID
cls.update_data('sys_setting', {"printer_id": printer_id_current.value})
return
def set_input_text(input_box, value): #设置INPUTBOX中的值
input_box.value = value
return
以上三个函数保存在文件名为local_utils.py中,然后主程序main的代码如下:
from nicegui import ui
import local_utils
import utils_tinydb
def title(title):
ui.label(title).classes('self-center text-5xl/[80%] font-bold m-5').style("font-family:HeiTi")
def header(text):
with ui.header(elevated=True).classes('w-full bg-primary text-white mt-2'):
ui.label(text).classes('fixed-top-right mt-2')
def footer(text):
with ui.footer().classes('w-full bg-primary text-white mb-2'):
ui.label(text).classes('fixed-bottom-right mb-2')
def ui_main(tinydb_class):
boot_settings = tinydb_class.all_data(tb_name='sys_setting')[0]
header('页眉')
title('信息管理系统设置')
with ui.grid(columns=2).classes('w-[80%] self-center row'):
with ui.tabs().classes('col-2 self-center').props('vertical') as tabs:
func0 = ui.tab("func0", label='首页', icon='home').style('color:red')
func1 = ui.tab('func1', label='功能一', icon='money').style('color:orange')
func2 = ui.tab('func2', label='功能二', icon='devices_other').style('color:black')
func3 = ui.tab('func3', label='功能三', icon='api').style('color:green')
func4 = ui.tab('func4', label='功能四', icon='apps').style('color:blue')
with ui.tab_panels(tabs, value=func0).classes('col self-center'):
with ui.tab_panel(func0):
ui.label('基础设置').classes('text-3xl/[80%] font-bold m-2').style("font-family:KaiTi")
with ui.column():
with ui.row():
printer_id_current = ui.input(label='打印机使用的纸张ID', value=boot_settings['printer_id']).classes('text-xl/[80%] m-2').style("font-family:FangSong")
ui.button("保存并设置默认纸张ID", on_click=lambda: local_utils.update_paper_size(tinydb_class, printer_id_current))
with ui.row():
printer_id_default = ui.input(label='当前默认纸张ID', value='').props('disable').classes('text-xl/[80%] m-2').style("font-family:FangSong")
ui.button("获取默认纸张ID", on_click=lambda: local_utils.set_input_text(printer_id_default, local_utils.get_paper_size()))
with ui.tab_panel(func1):
ui.label('功能一').classes('text-3xl/[80%] font-bold m-2').style("font-family:KaiTi")
with ui.tab_panel(func2):
ui.label('功能二').classes('text-3xl/[80%] font-bold m-2').style("font-family:KaiTi")
with ui.tab_panel(func3):
ui.label('功能三').classes('text-3xl/[80%] font-bold m-2').style("font-family:KaiTi")
with ui.tab_panel(func4):
ui.label('功能四').classes('text-3xl/[80%] font-bold m-2').style("font-family:KaiTi")
footer('页脚')
if __name__ == '__main__':
tinydb_class = utils_tinydb.Tiny_setting()
ui_main(tinydb_class)
ui.run(reload=False, native=True)
这样,一个加载启动项,同时可以设置更新启动项的初级程序就做好了,效果如下:
启动项加载成功,JSON文件中的PRINTER_ID是9
获取打印机的默认纸张成功,当前是A4纸,下方的INPUT也是9
将当前的纸张ID填入第一个INPUT中,然后点存保存,JSON文件中的PRINTER_ID保存为13
至此,一个基本的能够实现基本功能的NICEGUI界面搭建完成。后期踩入了哪些坑我再分享给大家。