游戏电视苹果数码历史美丽
投稿投诉
美丽时装
彩妆资讯
历史明星
乐活安卓
数码常识
驾车健康
苹果问答
网络发型
电视车载
室内电影
游戏科学
音乐整形

Python学习笔记数据库TinyDB配合多窗口界面及表格组

  本篇学习笔记将利用轻量级数据库TinyDB存储信息,配合Qt多窗口用户界面,实现数据库新增、修改、删除和查询等功能,最终使用Qt的表格组件将信息展现出来。
  一、轻量级数据库TinyDB介绍
  Python中的TinyDB,是一个纯Python编写的轻量级的面向文档的数据库,源码一共只有1800行代码,没有外部依赖项。TinyDB的数据储存方式主要是json文件,也就是Python中的字典类型。对于小型项目而言,使用TinyDB数据库非常适合。它有如下特点:轻便:源代码很少,小巧轻便可随意迁移:TinyDB基于面向文档的存储,数据库只有一个json文件,不依赖任何服务,拷贝即可迁移易用性:TinyDB的API非常简单和干净,易于使用非依赖性:TinyDB既不需要外部服务器,也不需要任何来自PyPI的依赖项,支持Python3。6以上的所有版本可扩展性:在中间件的帮助下,可以轻松扩展TinyDB行为,以满足特定的需求
  (一)创建json数据库和表
  TinyDB是一个第三方包,在使用之前需要先安装,如命令行格式:pipinstalltinydb,或者在集成开发环境中安装。
  创建数据库和表的代码模板如下:fromtinydbimportTinyDB导入TinyDB类dbTinyDB(mydb。json)创建名为mydb的json数据库tabledb。table(student)创建名为student的表db。close()关闭数据库
  (二)插入数据
  1、插入单条数据table。insert({name:张三,age:23,class:三年五班})table。insert({name:李四,age:30,class:三年一班})
  【注】插入语句insert的返回值是所添加数据在表中的索引值,表的索引值从1开始,顺序递增。运行以下代码观察索引值变化情况:fromtinydbimportTinyDBdbTinyDB(mydb。json)tabledb。table(student)index1table。insert({name:张三,age:23,class:三年五班})index2table。insert({name:李四,age:30,class:三年一班})print(index1,index2)db。close()运行结果:第一次运行的结果是12,第二次是34,依此类推
  2、插入多条数据fromtinydbimportTinyDBdbTinyDB(mydb。json)tabledb。table(student)data〔{name:小明,age:13,class:三年五班},{name:小刚,age:12,class:三年一班},{name:小强,age:15,class:三年一班},{name:小红,age:13,class:三年一班},{name:小花,age:14,class:三年一班}〕indextable。insertmultiple(data)插入多条数据,即数据以列表形式添加print(index)db。close()运行结果:〔1,2,3,4,5〕
  【注】在插入多条数据时,索引值是一个列表。
  (三)查询数据
  1、查询数据库中的表numdb。tables()print(num)运行结果:{student,default}
  【注】default表是默认存在的
  2、使用all函数查询所有数据stringtable。all()print(string)输出all函数查询到的所有结果运行结果:〔{name:小明,age:13,class:三年五班},{name:小刚,age:12,class:三年一班},{name:小强,age:15,class:三年一班},{name:小红,age:13,class:三年一班},{name:小花,age:14,class:三年一班},{name:小明,age:13,class:三年五班},{name:小刚,age:12,class:三年一班},{name:小强,age:15,class:三年一班},{name:小红,age:13,class:三年一班},{name:小花,age:14,class:三年一班}〕
  3、使用where进行条件查询fromtinydbimportTinyDB,where需要导入wherestr1table。search(where(name)小花)在表中查询名字是小花的记录str2table。search(where(age)13)print(str1)print(str2)运行结果:〔{name:小花,age:14,class:三年一班}〕〔{name:小强,age:15,class:三年一班},{name:小花,age:14,class:三年一班}〕
  4、使用Query查询
  Query是数据库查询组件,使用非常方便灵活,需要事先导入Query。演示代码如下:stuQueryQuery()创建查询对象querydatatable。search(stuQuery。cls三年一班)查询班级是三年一班的记录print(querydata)querydatatable。search(stuQuery。age13)查询年龄小于等于13的记录print(querydata)querydatatable。search(stuQuery。age13andstuQuery。cls三年五班)print(querydata)querydatatable。search((stuQuery。age13)(stuQuery。age14))print(querydata)运行结果:〔{name:小刚,age:12,cls:三年一班},{name:小强,age:15,cls:三年一班},{name:小红,age:13,cls:三年一班},{name:小花,age:14,cls:三年一班}〕〔{name:小明,age:13,cls:三年五班},{name:小刚,age:12,cls:三年一班},{name:小红,age:13,cls:三年一班}〕〔{name:小明,age:13,cls:三年五班}〕〔{name:小刚,age:12,cls:三年一班},{name:小强,age:15,cls:三年一班}〕
  【注】数据库中的字段名一定不能与系统的保留关键字重复,例如上面的学生数据库的班级字段,如果写成class,那么在使用Query查询时程序就会出错。
  (四)修改数据
  1、使用where方法indextable。update({cls:三年二班},where(name)小刚)print(修改记录的索引是:,index)print(table。search(where(name)小刚))运行结果:修改记录的索引是:〔2〕〔{name:小刚,age:12,cls:三年二班}〕
  2、使用Query方法indextable。update({cls:三年三班},stuQuery。name小强)print(修改记录的索引是:,index)print(table。search(where(name)小强))运行结果:修改记录的索引是:〔3〕〔{name:小强,age:15,cls:三年三班}〕
  (五)删除数据
  1、删除所有数据table。truncate()print(table。all())运行结果:〔〕
  2、删除符合条件的数据delindextable。remove(stuQuery。cls三年一班)删除班级是三年一班的数据print(删除的索引是:,delindex)print(table。all())运行结果:删除的索引是:〔4,5〕〔{name:小明,age:13,cls:三年五班},{name:小刚,age:12,cls:三年二班},{name:小强,age:15,cls:三年三班}〕二、多窗口图形界面介绍
  在实际开发项目时,多窗口图形界面是经常要使用的,例如登录窗口、点击功能按钮弹出对应功能实现窗口等等。使用多窗口图形界面,必须要理清窗口的继承关系,以及设置窗口的模态属性,也就是子窗口是否阻塞主窗口。
  (一)创建多窗口的基本模型
  下面实例演示创建多窗口的基础模型。首先,在Qt设计大师中创建一个主窗口和两个子窗口,主窗口设置了背景颜色,分别保存这三个窗口文件,并将三个窗口的ui文件转换成py文件,准备静态加载。
  1、加载多窗口代码fromPySide6。QtWidgetsimportQApplication,QWidgetfromPySide6。QtGuiimportQtfromuitest1importUiMForm导入窗口1的Ui类fromuitest2importUiSForm1导入窗口2的Ui类fromuitest3importUiSForm2导入窗口3的Ui类自定义主窗口的类classMainWindow(QWidget):definit(self):super(MainWindow,self)。init()self。ui1UiMForm()self。ui1。setupUi(self)设置两个子窗口对象值为None,代表窗口未打开self。swindow1Noneself。swindow2None主窗口的按钮单击信号和槽self。ui1。pushButton。clicked。connect(self。showForm)显示子窗口的方法defshowForm(self):如果子窗口1是未打开状态,则创建该窗口没有这个检测的环节,点击打开窗口按钮会反复打开子窗口ifself。swindow1isNone:self。swindow1SubWindow1()self。swindow1。show()self。swindow1。move(300,200)如果子窗口2是未打开状态,则创建该窗口ifself。swindow2isNone:self。swindow2SubWindow2()self。swindow2。show()self。swindow2。move(900,200)自定义子窗口1的类,继承主窗口的类MainWindow,因此主窗口的背景颜色设置在子窗口1里生效classSubWindow1(MainWindow):definit(self):super(SubWindow1,self)。init()self。ui2UiSForm1()self。ui2。setupUi(self)自定义子窗口2的类,继承通用组件QWidget,因此主窗口的背景颜色设置在子窗口2里不生效classSubWindow2(QWidget):definit(self):super(SubWindow2,self)。init()self。ui3UiSForm2()self。ui3。setupUi(self)ifnamemain:appQApplication(〔〕)windowMainWindow()window。show()app。exec()
  【注】子窗口1的自定义类继承了主窗口的自定义类MainWindow,子窗口2的自定义类继承通用组件QWidget,所以子窗口1的背景颜色跟主窗口一样,而子窗口2没有背景颜色。
  2、效果演示
  视频加载中。。。
  (二)实现子窗口跟随主窗口一起关闭
  在上面多窗口基本模型的视频演示中可以看到,主窗口和两个子窗口可以自由关闭,但是当主窗口关闭时,子窗口并不能跟随关闭。为了解决这个问题,我们要重写主类的closeEvent关闭事件方法。
  1、重写主类closeEvent方法代码一定要在主窗口的自定义类里书写此代码defcloseEvent(self,event):sys。exit(0)
  2、效果演示
  视频加载中。。。
  【注】程序运行后,关闭主窗口则子窗口1和子窗口2都跟着关闭;关闭子窗口1,主窗口和子窗口2也跟着关闭,因为子窗口1继承自主窗口类,关闭事件跟主窗口是相同的;关闭子窗口2不会影响主窗口和子窗口1。
  (三)设置子窗口模态属性
  在做多窗口项目开发时,有时要求子窗口不能同时打开,以免处理不好发生数据混乱的情况,例如新增数据和删除数据子窗口。为此,我们就需要用子窗口来阻塞主窗口进程,这里就需要设置子窗口的模态属性。
  1、在Qt设计大师中设置
  点击需要设置模态属性的子窗口,在窗口的QWidget属性设置中找到windowModality,将属性值改成ApplicationModal,保存窗口并将相应的ui文件转换成py文件即可。模态属性设置如下图:
  设置子窗口的模态属性
  2、在代码中设置self。swindow2SubWindow2()子窗口模态属性设置一定要放在show()方法之前self。swindow2。setWindowModality(Qt。ApplicationModal)self。swindow2。show()
  (四)多窗口演示完整代码importsysfromPySide6。QtWidgetsimportQApplication,QWidgetfromPySide6。QtGuiimportQtfromuitest1importUiMForm导入窗口1的Ui类fromuitest2importUiSForm1导入窗口2的Ui类fromuitest3importUiSForm2导入窗口3的Ui类自定义主窗口的类classMainWindow(QWidget):definit(self):super(MainWindow,self)。init()self。ui1UiMForm()self。ui1。setupUi(self)设置两个子窗口对象值为None,代表窗口未打开self。swindow1Noneself。swindow2None主窗口的按钮单击信号和槽self。ui1。pushButton。clicked。connect(self。showForm)显示子窗口的方法defshowForm(self):如果子窗口1是未打开状态,则创建该窗口ifself。swindow1isNone:self。swindow1SubWindow1()self。swindow1。show()self。swindow1。move(300,200)如果子窗口2是未打开状态,则创建该窗口ifself。swindow2isNone:self。swindow2SubWindow2()设置子窗口2的模态方式为阻塞主程序,或者在Qt设计大师的窗口属性里设置程序运行后,只有子窗口2是活动的,主窗口不可点击,只有子窗口2关闭后才可以操作主窗口self。swindow2。setWindowModality(Qt。ApplicationModal)self。swindow2。show()self。swindow2。move(900,200)重写父类的关闭事件方法,实现关闭主窗口后子窗口跟着关闭的功能defcloseEvent(self,event):sys。exit(0)自定义子窗口1的类,继承主窗口的类MainWindow,因此主窗口的背景颜色设置在子窗口1里生效classSubWindow1(MainWindow):definit(self):super(SubWindow1,self)。init()self。ui2UiSForm1()self。ui2。setupUi(self)自定义子窗口2的类,继承通用组件QWidget,因此主窗口的背景颜色设置在子窗口2里不生效classSubWindow2(QWidget):definit(self):super(SubWindow2,self)。init()self。ui3UiSForm2()self。ui3。setupUi(self)ifnamemain:appQApplication(〔〕)windowMainWindow()window。show()app。exec()
  视频加载中。。。三、综合实例开发
  在介绍图形界面开发之PySimpleGUI模块时,我们使用SQLite3和PySimpleGUI模块制作了一个员工档案信息管理系统,现在我们使用PySide6和TinyDB对该系统进行重新开发,旨在加深对PySide6和TinyDB的理解,并未在安全性方面做任何处理。
  (一)准备数据库
  1、数据库描述
  本案例采用轻量级数据库TinyDB存储员工档案信息。数据库、表和字段设置如下:【数据库文件】:company。json【档案信息表】:employee【字段】:编号、姓名、性别、出生年月、民族、籍贯、党派、学历、职称、身份证号码电话号码、所在部门、获得的荣誉、所受的处罚【用户名密码保存表】:user字段:uid、pwd
  2、初始化数据库
  首先创建一个init。py文件,使用代码创建数据库和用户名密码保存表,并插入一条默认用户名和密码数据,代码如下:fromtinydbimportTinyDBdbTinyDB(company。json)创建json数据库,数据库名称为company。jsontabledb。table(user)创建用来存储用户名和密码的表,表名为usertable。insert({uid:admin,pwd:1111})设置初始用户名和密码db。close()
  (二)设计窗口
  窗口包括:主窗口,登录窗口,新增信息窗口,查询删除信息窗口,修改信息窗口和修改密码窗口。
  1、主窗口
  在Qt设计大师里创建主窗口时,最好使用MainWindow模版,如果不需要菜单栏、工具栏和地址栏可以手动去除。MainWindow类的窗口功能比较健全,设置背景图片、布局等都不会出现问题。采用Form类创建的窗口,在代码中创建窗口类时,如果继承QMainWindow类,那么布局会混乱;如果继承QWidget类,那么背景图片就会不显示。
  我在做这个实例时,就是采用Form模版创建的主窗口,然后在代码中创建窗口类时继承QWidget类,就发生了背景图片不显示的情况,折磨了很久才找到原因。由于不想重新设计主窗口,于是将主窗口的最大尺寸和最小尺寸均设置成窗口实际尺寸,让窗口不能通过拖动改变尺寸,也就不需要布局了,最后在创建窗口类的代码中继承QMainWindow类,总算解决了背景图片不显示的问题。窗口ui文件名称:uimain。ui窗口对象名称:MainForm,由于是多窗口应用,因此窗口对象的名称最好不采用默认的Form或者MainWindow包含组件:四个ToolButton,工具按钮的toolButtonStyle属性设置为ToolButtonTextUnderIcon,即按钮文本在图标下面。autoRaise属性设置为真,即工具按钮自动浮起,否则是凹陷状态,按钮周围有外框影响美观背景图片:在窗口对象的样式表中,使用MainForm{}的形式设置背景图片,这是为了只给名称为MainForm的组件即窗口添加背景图片,否则窗口上的所有元素都会加载这个背景图片。样式表代码如下:MainForm{backgroundimage:url(:imagesiconbackground。jpg);}窗口外观:如下图
  主窗口示例图片
  2、登录窗口
  设计登录窗口不要采用Dialog模版,无论点击OK还是Cancel按钮,Dialog类的窗口都会关闭,不能持久显示。窗口ui文件名称:uilogin。ui窗口对象名称:LoginForm包含组件:两个标签组件,两个单行文本输入框组件,一个按钮组件背景图片:与主窗口设置背景图片方法相同窗口外观:如下图
  登录窗口示例图片
  3、新增信息窗口窗口ui文件名称:uiadd。ui窗口对象名称:AddForm包含组件:一个GroupBox容器类组件,用来装载录入员工基本信息的所有组件,起到归类的作用。一个TabWidget标签组件,用来放置获得的荣誉和所受的处罚两个多行文本输入框,节省空间。一个TableWidget表格组件,用来显示新录入的员工信息。剩余是标签、单行文本输入框和按钮组件,整个窗口设置了布局,支持拖放改变窗口大小。另外,在窗口的样式表中对表格组件的标题栏进行了设置,样式表代码如下:QHeaderView::section{;backgroundcolor:rgb(225,225,225);height:28px;}背景图片:无窗口外观:如下图
  新增信息窗口示例图片
  4、查询删除信息窗口窗口ui文件名称:uisearchdel。ui窗口对象名称:SDForm包含组件:一个TableWidget表格组件,标题栏设置与新增信息中相同。剩余是标签、单行文本输入框和按钮组件,整个窗口设置了布局,支持拖放改变窗口大小背景图片:无窗口外观:如下图
  查询删除信息窗口示例图片
  5、修改信息窗口窗口ui文件名称:uichange。ui窗口对象名称:ChangeForm包含组件:与新增信息窗口基本相同背景图片:无窗口外观:如下图
  修改信息窗口示例图片
  (三)代码部分
  1、登录窗口和主窗口显示代码
  (1)思路分析创建登录窗口类创建主窗口类创建登录窗口实例对象显示登录窗口,即程序运行首先显示登录窗口判断登录是否成功,如果登录成功,则关闭登录窗口本身,然后创建主窗口实例对象并显示主窗口
  (2)实例代码fromPySide6。QtWidgetsimportQApplication,QMainWindow,QMessageBoxfromtinydbimportTinyDB,QueryfromuiloginimportUiLoginForm导入登录窗口ui文件fromuimainimportUiMainForm导入主窗口ui文件创建登录窗口类,这里必须继承QMainWindow类,如果继承QWidget,那么背景图片无法显示classLoginWindow(QMainWindow):definit(self):super(LoginWindow,self)。init()self。uiLoginUiLoginForm()self。uiLogin。setupUi(self)self。mainwindowNone预设主窗口对象密码输入框回车和登录按钮单击信号,都连接到登录方法self。uiLogin。lineEdit2。returnPressed。connect(self。login)self。uiLogin。pushButton。clicked。connect(self。login)登录方法deflogin(self):ifself。uiLogin。lineEdit。text()orself。uiLogin。lineEdit2。text():returndbTinyDB(company。json)tabledb。table(user)queryQuery()usernameadmin搜索结果是列表包含字典的格式,因此需要先用索引值获得字典数据,再用字典的key获取value值passwordtable。search(query。uidusername)〔0〕〔pwd〕ifself。uiLogin。lineEdit。text()usernameandself。uiLogin。lineEdit2。text()password:self。close()如果登录成功,则登录窗口本身关闭。因为不再使用登录窗口,所以没有使用隐藏方法。self。mainwindowMainWindow()创建主窗口实例对象self。mainwindow。show()显示主窗口else:QMessageBox。information(self,提示信息,用户名或密码错误,请重新输入!)创建主窗口类,同样要继承QMainWindow类,以显示背景图片classMainWindow(QMainWindow):definit(self):super(MainWindow,self)。init()self。uiMainUiMainForm()self。uiMain。setupUi(self)ifnamemain:appQApplication(〔〕)windowLoginWindow()创建登录窗口实例对象window。show()显示登录窗口app。exec()
  2、主程序完整代码
  在主程序中,除了上面介绍的登录窗口和主程序窗口显示代码外,剩下就是显示新增信息、查询删除信息和修改信息窗口的代码。每个窗口具体功能实现部分,都在各自的py文件中,在主程序中将这些py文件以模块的形式导入,再引用模块内的窗口类就可以了。修改密码功能,在主程序中直接采用QInputDialog输入对话框完成。主程序文件名为mainProgram。py,完整代码如下:fromPySide6。QtWidgetsimportQApplication,QMainWindow,QMessageBox,QInputDialogfromPySide6。QtGuiimportQtfromtinydbimportTinyDB,QueryfromuiloginimportUiLoginFormfromuimainimportUiMainFormfromaddimportAddWindow导入新增信息模块即py文件中的窗口类fromsearchdelimportSDWindow导入搜索删除信息模块中的窗口类fromchangeimportChangeWindow导入修改信息模块中的窗口类创建登录窗口类,这里必须继承QMainWindow类,如果继承QWidget,那么背景图片无法显示classLoginWindow(QMainWindow):definit(self):super(LoginWindow,self)。init()self。uiLoginUiLoginForm()self。uiLogin。setupUi(self)self。mainwindowNone预设主窗口对象密码输入框回车和登录按钮单击信号,都连接到登录方法self。uiLogin。lineEdit2。returnPressed。connect(self。login)self。uiLogin。pushButton。clicked。connect(self。login)登录方法deflogin(self):ifself。uiLogin。lineEdit。text()orself。uiLogin。lineEdit2。text():returndbTinyDB(company。json)tabledb。table(user)queryQuery()usernameadmin搜索结果是列表包含字典的格式,因此需要先用索引值获得字典数据,再用字典的key获取value值passwordtable。search(query。uidusername)〔0〕〔pwd〕db。close()ifself。uiLogin。lineEdit。text()usernameandself。uiLogin。lineEdit2。text()password:self。close()如果登录成功,则登录窗口本身关闭。因为不再使用登录窗口,所以没有使用隐藏方法。self。mainwindowMainWindow()创建主窗口实例对象self。mainwindow。show()显示主窗口else:QMessageBox。information(self,提示信息,用户名或密码错误,请重新输入!)创建主窗口类,同样要继承QMainWindow类,以显示背景图片classMainWindow(QMainWindow):definit(self):super(MainWindow,self)。init()self。uiMainUiMainForm()self。uiMain。setupUi(self)self。addwindowNone预设新增信息窗口对象self。searchwindowNone预设搜索删除信息窗口对象self。changewindowNone预设修改信息窗口对象self。uiMain。toolButtonadd。clicked。connect(self。showadd)新增信息按钮点击信号和槽self。uiMain。toolButtonsearch。clicked。connect(self。showsearch)查询删除信息按钮点击信号和槽self。uiMain。toolButtonchange。clicked。connect(self。showchange)新增信息按钮点击信号和槽self。uiMain。toolButtonpwd。clicked。connect(self。showpwd)修改密码按钮单击信号和槽显示新增信息窗口方法defshowadd(self):self。addwindowAddWindow()self。addwindow。setWindowModality(Qt。ApplicationModal)为窗口设置模态属性self。addwindow。show()显示查询删除信息窗口方法defshowsearch(self):self。searchwindowSDWindow()self。searchwindow。setWindowModality(Qt。ApplicationModal)为窗口设置模态属性self。searchwindow。show()显示修改信息窗口方法defshowchange(self):self。changewindowChangeWindow()self。changewindow。setWindowModality(Qt。ApplicationModal)为窗口设置模态属性self。changewindow。show()修改密码方法defshowpwd(self):pwd1,okPressed1QInputDialog。getText(self,修改密码,请输入新密码:)ifokPressed1:pwd2,okPressed2QInputDialog。getText(self,确认修改,请再次输入新密码:)ifokPressed2:ifpwd1pwd2:dbTinyDB(company。json)tabledb。table(user)queryQuery()table。update({pwd:pwd1},query。uidadmin)db。close()QMessageBox。information(self,修改密码,密码修改成功!)else:QMessageBox。information(self,修改密码,两次输入不相同,请重新输入!)ifnamemain:appQApplication(〔〕)windowLoginWindow()创建登录窗口实例对象window。show()显示登录窗口app。exec()
  3、新增信息模块代码
  新增信息模块名为add。py,代码如下:importcopyfromPySide6。QtWidgetsimportQApplication,QWidget,QMessageBox,QTableWidgetItemfromPySide6。QtGuiimportQtfromtinydbimportTinyDBfromuiaddimportUiAddForm创建新增信息窗口类classAddWindow(QWidget):definit(self):super(AddWindow,self)。init()self。uiAddUiAddForm()self。uiAdd。setupUi(self)self。addlist〔〕定义存储所有新增信息的列表,为的是往数据库里添加self。adddictdict()定义存储每行新增信息的字典self。uiAdd。pushButton。clicked。connect(self。addList)添加到新增列表按钮信号和槽self。uiAdd。pushButton2。clicked。connect(self。saveDB)保存到数据库按钮信号和槽self。tableinit()调用table表格初始化方法self。idinit()调用编号初始化方法编号初始化方法,自动生成编号defidinit(self):dbTinyDB(company。json)tabledb。table(employee)contenttable。all()读取数据表的所有内容rowsself。uiAdd。tableWidget。rowCount()获取Table的行数ifrows0andcontent〔〕:self。uiAdd。edit0。setText(A001)如果数据表和Table中的内容都是空的,则编号设置为A001self。uiAdd。edit1。setFocus()将焦点设置在姓名输入框returnifrows!0:如果Table中有数据,则取得最后一行的编号iddataself。uiAdd。tableWidget。item(rows1,0)。text()else:iddatacontent〔1〕〔编号〕如果Table中没有数据,则取得数据表中最后一条记录的编号数据idnewA03d(int(iddata〔1:〕)1)将原有编号后面数字加1,一共显示3位,前面用0补充self。uiAdd。edit0。setText(idnew)将新增信息窗口的编号输入框内容设置为新编号self。uiAdd。edit1。setFocus()将焦点设置在姓名输入框表格初始化方法deftableinit(self):调整各列的列宽self。uiAdd。tableWidget。setColumnWidth(0,50)self。uiAdd。tableWidget。setColumnWidth(1,60)self。uiAdd。tableWidget。setColumnWidth(2,40)self。uiAdd。tableWidget。setColumnWidth(3,60)self。uiAdd。tableWidget。setColumnWidth(4,40)self。uiAdd。tableWidget。setColumnWidth(5,60)self。uiAdd。tableWidget。setColumnWidth(6,60)self。uiAdd。tableWidget。setColumnWidth(7,60)self。uiAdd。tableWidget。setColumnWidth(8,80)self。uiAdd。tableWidget。setColumnWidth(9,150)self。uiAdd。tableWidget。setColumnWidth(10,90)添加到新增列表按钮单击方法defaddList(self):判断编号和姓名输入框内容是否为空ifself。uiAdd。edit0。text()orself。uiAdd。edit1。text():QMessageBox。critical(self,错误信息,编号和姓名不能为空,请重新输入)else:rowself。uiAdd。tableWidget。rowCount()获取表格总行数self。uiAdd。tableWidget。setRowCount(row1)表格当前行等于总行数加1将单行文本输入框的名称设置为连续序列形式,如edit0、edit1,利用eval函数循环将各个单行文本输入框内容添加到表格当前行中forcolinrange(12):labeltexteval(fself。uiAdd。label{col}。text())edittexteval(fself。uiAdd。edit{col}。text())self。uiAdd。tableWidget。setItem(row,col,QTableWidgetItem(edittext))设置单元格对齐方式,需要使用Qt类的AlignmentFlag属性self。uiAdd。tableWidget。item(row,col)。setTextAlignment(Qt。AlignmentFlag。AlignCenter)构建新增信息的字典数据,下面语句还可以写成self。adddict。update({f{labeltext}:f{edittext}})self。adddict〔f{labeltext}〕edittext单行文本输入框内容添加完毕后,将两个多行文本输入框的内容添加到最后两列中edittextself。uiAdd。plainTextEdit0。toPlainText()self。uiAdd。tableWidget。setItem(row,12,QTableWidgetItem(edittext))self。adddict〔获得的荣誉〕edittext字典里也添加该信息edittextself。uiAdd。plainTextEdit1。toPlainText()self。uiAdd。tableWidget。setItem(row,13,QTableWidgetItem(edittext))self。adddict〔所受的处罚〕edittext将一行信息的字典添加到列表中,这里必须对字典进行深拷贝,否则下次输入改变字典内容,列表内容随着更改self。addlist。append(copy。deepcopy(self。adddict))使用跟上面相同方法,将所有输入框内容清除foriinrange(12):eval(fself。uiAdd。edit{i}。clear())self。uiAdd。plainTextEdit0。clear()self。uiAdd。plainTextEdit1。clear()self。idinit()所有输入框内容清空后,调用编号初始化方法,自动生成编号保存到数据库按钮单击方法defsaveDB(self):choiceQMessageBox。question(self,确认信息,确认要将数据保存到数据库吗?)ifchoiceQMessageBox。No:returndbTinyDB(company。json)tabledb。table(employee)table。insertmultiple(self。addlist)QMessageBox。information(self,提示信息,数据保存成功!)print(table。all())self。uiAdd。tableWidget。clearContents()清除表格内容,但不清除标题,clear方法会连标题都清除self。uiAdd。tableWidget。setRowCount(0)self。addlist。clear()ifnamemain:appQApplication(〔〕)windowAddWindow()window。show()app。exec()
  运行效果:
  视频加载中。。。
  4、查询删除信息模块代码
  新增信息模块名为searchdel。py,代码如下:fromPySide6。QtWidgetsimportQApplication,QWidget,QTableWidgetItem,QMessageBoxfromPySide6importQtCorefromPySide6。QtGuiimportQtfromuisearchdelimportUiSDFormfromtinydbimportTinyDB,QueryclassSDWindow(QWidget):definit(self):super(SDWindow,self)。init()self。uiSDUiSDForm()self。uiSD。setupUi(self)self。tableinit()调用表格初始化方法self。uiSD。buttons。clicked。connect(self。search)提交搜索按钮单击信号self。uiSD。buttond。clicked。connect(self。delete)删除按钮单击信号表格初始化方法deftableinit(self):调整各列的列宽self。uiSD。tableWidget。setColumnWidth(0,50)self。uiSD。tableWidget。setColumnWidth(1,60)self。uiSD。tableWidget。setColumnWidth(2,40)self。uiSD。tableWidget。setColumnWidth(3,60)self。uiSD。tableWidget。setColumnWidth(4,40)self。uiSD。tableWidget。setColumnWidth(5,60)self。uiSD。tableWidget。setColumnWidth(6,60)self。uiSD。tableWidget。setColumnWidth(7,60)self。uiSD。tableWidget。setColumnWidth(8,80)self。uiSD。tableWidget。setColumnWidth(9,150)self。uiSD。tableWidget。setColumnWidth(10,90)defsearch(self):dbTinyDB(company。json)tabledb。table(employee)queryQuery()self。querydata〔〕按照所输入位置和内容搜索信息ifself。uiSD。editid。text():self。querydatatable。search(query。编号self。uiSD。editid。text())ifself。uiSD。editname。text():self。querydatatable。search(query。姓名self。uiSD。editname。text())ifself。uiSD。editcard。text():self。querydatatable。search(query。身份证号码self。uiSD。editcard。text())ifself。uiSD。editcls。text():self。querydatatable。search(query。所在部门self。uiSD。editcls。text())db。close()self。showdata(self。querydata)调用显示数据方法显示数据方法defshowdata(self,data):row0初始行为0self。uiSD。tableWidget。setRowCount(len(data))设置表格总行数为搜索到的记录数foritemindata:col0初始列为0forkeyinitem:self。uiSD。tableWidget。setItem(row,col,QTableWidgetItem(item〔key〕))设置单元格对齐方式,需要使用Qt类的AlignmentFlag属性self。uiSD。tableWidget。item(row,col)。setTextAlignment(Qt。AlignmentFlag。AlignCenter)col1row1删除信息按钮单击方法defdelete(self):selecteddataself。uiSD。tableWidget。selectedItems()获取选中的所有表格项目self。idlist〔〕定义存储选中信息的编号列表rowslen(selecteddata)14计算一共选中几行信息,因为获取的数据是所有单元格,每行有14个单元格foriinrange(rows):self。idlist。append(selecteddata〔i14〕。text())循环获取所有准备删除的编号数据,放置在列表中choiceQMessageBox。question(self,删除信息,f确认要删除编号为:{self。idlist}的数据吗?)ifchoiceQMessageBox。No:returndbTinyDB(company。json)tabledb。table(employee)queryQuery()将数据库中包含要删除编号的记录全部删掉foriinself。idlist:table。remove(query。编号i)db。close()self。search()调用查询方法,更新表格显示QMessageBox。information(self,删除信息,信息删除成功!)ifnamemain:appQApplication(〔〕)windowSDWindow()window。show()app。exec()
  运行效果:
  视频加载中。。。
  5、修改信息模块代码
  修改信息模块名为change。py,代码如下:fromPySide6。QtWidgetsimportQApplication,QWidget,QMessageBoxfromtinydbimportTinyDB,QueryfromuichangeimportUiChangeForm创建修改信息窗口类classChangeWindow(QWidget):definit(self):super(ChangeWindow,self)。init()self。uiChangeUiChangeForm()self。uiChange。setupUi(self)self。loaddata〔〕预设存储要修改信息列表变量self。uiChange。pushButton。clicked。connect(self。load)读入信息按钮信号self。uiChange。pushButton2。clicked。connect(self。save)保存信息按钮信号读入信息方法defload(self):ifnotself。uiChange。edit0。text():QMessageBox。information(self,提示信息,请输入要修改信息的编号,然后点读入信息按钮!)returndbTinyDB(company。json)tabledb。table(employee)queryQuery()self。loaddatatable。search(query。编号self。uiChange。edit0。text())db。close()iflen(self。loaddata)0:QMessageBox。information(self,提示信息,输入的编号不存在,请重新输入!)returni0foriteminself。loaddata〔0〕。values():ifiin(0,12,13):跳过第0、12和13条项目i1continueeval(fself。uiChange。edit{i}。setEnabled(True))循环设置单行文本输入框的可用状态为真eval(fself。uiChange。edit{i}。setText(item))设置文本输入框的内容为读入的相应数据i1设置两个多行文本编辑器的状态和内容self。uiChange。plainTextEdit0。setEnabled(True)self。uiChange。plainTextEdit1。setEnabled(True)self。uiChange。plainTextEdit0。setPlainText(self。loaddata〔0〕〔获得的荣誉〕)self。uiChange。plainTextEdit1。setPlainText(self。loaddata〔0〕〔所受的处罚〕)保存信息方法defsave(self):dbTinyDB(company。json)tabledb。table(employee)queryQuery()foriinrange(12):以相应的标签的文本为key,以对应的单行文本输入框的内容为value,更新数据库内容keyeval(fself。uiChange。label{i}。text())valueeval(fself。uiChange。edit{i}。text())table。update({key:value},query。编号self。uiChange。edit0。text())table。update({获得的荣誉:self。uiChange。plainTextEdit0。toPlainText()},query。编号self。uiChange。edit0。text())table。update({所受的处罚:self。uiChange。plainTextEdit1。toPlainText()},query。编号self。uiChange。edit0。text())QMessageBox。information(self,提示信息,信息保存成功!)ifnamemain:appQApplication(〔〕)windowChangeWindow()window。show()app。exec()
  运行效果:
  视频加载中。。。
  6、修改密码功能
  修改密码功能没有设计窗口,而是在主程序中直接采用QInputDialog输入对话框完成。代码如下:修改密码方法defshowpwd(self):pwd1,okPressed1QInputDialog。getText(self,修改密码,请输入新密码:)ifokPressed1:pwd2,okPressed2QInputDialog。getText(self,确认修改,请再次输入新密码:)ifokPressed2:ifpwd1pwd2:dbTinyDB(company。json)tabledb。table(user)queryQuery()table。update({pwd:pwd1},query。uidadmin)db。close()QMessageBox。information(self,修改密码,密码修改成功!)else:QMessageBox。information(self,修改密码,两次输入不相同,请重新输入!)
  (四)整体效果演示
  视频加载中。。。

海上武则天,打了英国一耳光来源:国馆(ID:guoguan5000)中国最后的海贼王前半生海盗,后半生赌徒。这个女人一生都在恶的边缘行走,却被英国学者康士坦载入史册,成为西方人眼中数一……张一山在凌晨官宣新恋情?没想到,这一对也被曝光了前几天,男童星聚众吸毒嫖娼的传闻在网上疯传。消息一出,张一山就立刻被推到了风口浪尖,成了怀疑的对象。更多内部消息传出。让大家相信他是下一个李易峰。为什么……正式离开北控男篮!CBA榜眼被马布里放弃,还有机会证明自己吗根据篮球记者宋翔透露,北控男篮一共有14名球员前往长春赛区,兰兹博格和孙思尧没有去。很多球迷问兰兹博格为什么不和北控男篮一起?据了解是兰兹博格身体状态还没有恢复到最佳,等达到比……爸爸在你身后女儿今年18了,上了大学,学会了独自买机票,独自登机,独自回家。回忆起十一年前她刚上小学的时候,第一次独自走路上学的场景。感受颇多,那年她七岁。女儿胆小,天生的,看见小虫……鱼禽蛋和瘦肉食用要适量因为人们生活水平的提高,以前只有逢年过节才会大鱼大肉,到现在的随时随地都能整一桌丰盛的食物,鱼、禽、蛋、畜肉更是不可少,随之而来的是越来越多的人过胖,越来越多的人患有脑心血管方……在氤氲着茶香的光阴里落笔成暖光阴在不疾不徐的流淌,陈年的过往在浮浮沉沉间,一时走远,一时搁浅,两岸的花开花谢,凋零残落总是在不停的上演,更迭的四季脚步从不会乱,只是我们的陌上不时地相遇离散,尝尽人间的苦楚……抗日战争中,解放军国军日军阵亡的最高将领分别是谁?1931年到1945年,中国走过了14年的抗战征程,中华大地曾经生灵涂炭。日本发动的此次侵略战争,于中日双方而言,都是一场浩劫。1945年,日本天皇宣布无条件投降,中国实现全胜……护肤中,外油内干究竟是什么样的肤质?该怎么护理?皮肤发干,针对性的措施是补水和保湿,但是有不少朋友都反映:我给肌肤补水,到最后却外油内干,是为什么呢?下面我们就来了解一下1、什么是外油内干其实问题在于干,干……蒋介石3发电报,盛情邀请毛泽东赴鸿门宴,毛泽东机智应对重庆谈判重庆谈判各代表合照蒋介石说:只有消灭中共,才能达成我们的任务!1945年,中国人民的抗日战争结束之时,中国国内的阶级矛盾逐渐上升为社会的主要矛盾。以国民党为……河南解放后,杨靖宇子女站在路边问部队知道我的父亲在哪里吗?广阔的人世间,万事万物皆有一个结局,有的结局是圆满的,就像戏台上一场合家欢的大戏落幕,最后小姐寻得郎君,病人寻得解药。而有的结局是不圆满的,就像是一阴一阳的天人永隔,或者……李沁工作室公开纳税信息,连续4年评分A级,已成平台香饽饽2022年,本来随着国内疫情的复发,娱乐圈明星偷税已经成了很遥远的话题,可谁也没想到,因为邓伦的出现,明星税务检查又成了近段时间网友热议的话题,3月15日,邓伦被税务部门曝出逃……蒋介石的杀手锏引以为傲的五大王牌军,如何在4年内毁灭?辽沈战役关门打狗,淮海战役中间突破,平津战役先打两头、后取中间。在毛主席的带领下,人民军队以摧枯拉朽之势夺取三大战役胜利,将鲜红的旗帜插遍神州大地,古老的中国由此掀开新的篇章。……
两宋风云第二十四讲死里逃生完颜兀术一心想打个胜仗挽回面子,宋高宗也不想和金国撕破脸,所以虽然宋军获胜,宋高宗仍然下旨,命令宋军只可防守不要进攻。而此时岳家军尚未赶到,所以完颜兀术认为,这是一个挽回面子的……恩比德破7000分用282场比赛,詹姆斯杜兰特库里等人几场?北京时间12月27日,在今天费城76人117:96大胜奇才的比赛中,恩比德砍下36分13篮板的大号两双数据。本场比赛之后,27岁的恩比德也迎来了生涯的里程碑,常规赛总得分突破7……1840年,买办开始兴起,致使清朝对西方列强进入妥协时代咸丰朝妥协派是在国内阶级矛盾和中外民族矛盾同时激化的情况下,部分统治集团成员形成的一个以挽救清朝统治为目的、以改变闭关观念和放弃部分中国权益为条件、联合西方列强共同镇压农民起义……出游机票酒店价格猛增,三亚平替突然火了据钱江晚报消息三天的元旦假期结束。去哪儿数据显示,元旦期间,成都、上海、深圳、广州、杭州、昆明等城市出发的预订量超过去年元旦。同程数据显示,洛阳、哈尔滨、西双……卤味三巨头利润夺命狂跌,陷入了这三大困局记者马越编辑牙韩翔疫情下的求生大考卤味三巨头绝味食品、周黑鸭和煌上煌这次都没表现好。2月13日晚,周黑鸭发布盈利警告称,预计2022年净利润不少于0。2亿元,……旅游年票免费送,四轮共派发800张五月,是繁花盛开,共赴文旅盛宴的美好时节。围绕518国际博物馆日和519中国旅游日,我市将开展一系列丰富多彩的活动。其中,为提高市民的对这两场活动知晓度、参与度,市文旅广体局特……32岁李讷离婚,携子独居,毛主席落泪闺女的婚事实在是草率啊毛主席的女儿李讷在1972年离婚,听罢这个消息,毛主席竟然落下泪来。这位在战场上无惧生死的伟人那时候竟然流着泪表示:是我不好,李讷的婚事实在是太草率了啊!后来毛主席为了帮……海因里希希姆莱(5)背叛第三帝国难恕滔天大罪希姆莱是720事件(谋杀希特勒)的最大受益者。这次事件之后,希姆莱几乎没有了与之抗衡的对手,成为第三帝国最重要组织党卫队的主宰,统帅着38个师的武装党卫队。他权掌内政部,作为新……明朝周王世系朱元璋五子朱橚就藩开封,一府分出70多支郡王周定王朱橚(1361年1425年),是明太祖朱元璋第五子。他在洪武三年(1370年)被封为吴王,洪武十一年(1378)改封为周王,洪武十四年(1381年)就藩开封,洪熙元年(1……奔四的我每个小时30。486年的虎,转眼到了奔四的年纪,回头看看自己走过的路,坎坎坷坷。人都说不经历风雨,怎能见彩虹我只想说一句,我经历了暴风雨甚至差点死在里面,彩虹啊,彩虹,你在哪里?本不想在……慈禧太后,真的单纯的为咸丰帝守寡了几十年吗?慈禧太后守寡的问题,回答起来确实有点复杂,我们慢慢谈:说句公道话,慈禧太后执政晚清近半个世纪,确实做过一些匪夷所思,阴狠手辣又卖国的事。从某些层面上讲,也确实把本就……苹果终于松口,14Pro或迎来256G标配,国产安卓早已走在今天我刷到一个新闻,传闻下个月登场的iphone14pro的储存容量将会达到256G起步,我觉得这对于苹果用户来说准是一个好消息。众所周知,在手机行业内,苹果手机的性能寿……
友情链接:易事利快生活快传网聚热点七猫云快好知快百科中准网快好找文好找中准网快软网