前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >PyQt+SQLite构建一个简单的账号管理GUI程序

PyQt+SQLite构建一个简单的账号管理GUI程序

作者头像
测试邦
发布2019-10-21 17:08:14
3.7K0
发布2019-10-21 17:08:14
举报
文章被收录于专栏:测试邦测试邦测试邦
背景

相信有很多的测试同学,在日常的工作中都会需要去写一些辅助测试的小工具或者脚本,我们除了保证工具的可用性之外,有时还需要做一些图形界面上的开发以便在公司或者小组内推广。本文旨在以实战的形式,完成一个简单的账号管理GUI程序,实现完整的增、删、改、查功能项,带大家了解如何系统的开发一个账号管理GUI程序。

最终效果
使用框架

PyQt5 + SQLite3

代码设计
  • UI代码和操作数据库的代码分开为两个文件,FirstApp类和Tools类。
import sys
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from Tools import *

class FirstApp(QMainWindow):

    def __init__(self):
        super(FirstApp, self).__init__()

        # 创建数据库
        Tools.createDb()
        # 创建ui布局
        self.initMainUi()
        # 初始化表格
        self.initTable()
    
    def initTable(self):
        pass
    
    def initTable(self):
        pass
          
#程序主入口
if __name__ == '__main__':
    app=QApplication(sys.argv)
    firstapp = FirstApp()
    firstapp.show()
    sys.exit(app.exec_())
  • 启动程序时,检查同级路径下是否有SQLite数据库文件,如果没有则创建它,并插入示例数据,方法为Tools.createDb()
import sqlite3
import os

class Tools():

    @staticmethod
    def createDb():

        # 如果路径下没有db文件,重新创建并插入示例数据
        if os.path.exists('mydata.db') == False:
            connect = sqlite3.connect('mydata.db')
            c = connect.cursor()
            c.execute('''create table mydata(
                id INTEGER PRIMARY KEY AUTOINCREMENT,
                Website varchar(1000),
                username varchar(1000),
                passwd varchar(1000)
            );
            ''')
            connect.commit()
            c.execute("insert into mydata values(1,'qq','qq','test123')")
            connect.commit()
            connect.close()
  • 创建ui布局,主程序布局为一个table控件+三个按钮控件,用栅格布局方式排列,如下图,主界面QMainWindows中包含着一层QWidget,QWidget中使用栅格布局GridLayout,GridLayout中为y一个表格控件 + 三个按钮控件。
#布局
  def initMainUi(self):
        
        # 设置主界面的大小,标题及图标
        self.resize(450, 270)
        self.setWindowTitle('FirstApp')
        self.setWindowIcon(QIcon('icon.png'))
        
        # 第二层的QWidget控件
        self.qwidget = QWidget()
        
        # 栅格布局
        grid = QGridLayout()
        
        # 创建表格控件和按钮控件
        self.tablewidget = QTableWidget()
        self.addButton = QPushButton('新增')
        self.editButton = QPushButton('修改')
        self.delButton = QPushButton('删除')

        # 设置控件在栅格中的位置
        grid.addWidget(self.tablewidget,1,1,1,3)
        grid.addWidget(self.addButton,2,1)
        grid.addWidget(self.editButton,2,2)
        grid.addWidget(self.delButton,2,3)
        
        # 添加栅格布局到qwidget
        self.qwidget.setLayout(grid)
        
        # 设置qwidget到主界面中
        self.setCentralWidget(self.qwidget)

        #给按钮绑定点击方法
        self.addButton.clicked.connect(self.addDef)
        self.editButton.clicked.connect(self.editDef)
        self.delButton.clicked.connect(self.delDef)
  • 初始化表格
def initTable(self):

        # 设置表格的列数为4
        self.tablewidget.setColumnCount(4)

        # 水平和垂直方向设置为正好填满表格
        self.tablewidget.horizontalHeader().setStretchLastSection(True)
        self.tablewidget.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)

        # 设置表格的表头,并设置为不可编辑
        headerlabels = ['序号','网站', '账号', '密码']
        self.tablewidget.setHorizontalHeaderLabels(headerlabels)
        self.tablewidget.setEditTriggers(QAbstractItemView.NoEditTriggers)

        # 隐藏id列,不显示数据的id也就是主键,这里的主键只用来删除和修改数据时使用
        self.tablewidget.setColumnHidden(0, True);

        # 不显示单元格
        self.tablewidget.setShowGrid(False)

        # 设置表格选择行为为 只能一行一行选择
        self.tablewidget.setSelectionBehavior(QAbstractItemView.SelectRows)

        # 初始化表格数据
        self.flushTable()
  • 刷新表格数据
def flushTable(self):

        # 从数据表中获取数据
        data_list = Tools.getData()

        # 设置表格的行数,和数据的数量相关
        self.tablewidget.setRowCount(len(data_list))

        # 设置表格的数据
        for index in range(len(data_list)):
            self.tablewidget.setItem(index,0,QTableWidgetItem(str(data_list[index][0])))
            self.tablewidget.setItem(index,1,QTableWidgetItem(data_list[index][1]))
            self.tablewidget.setItem(index,2,QTableWidgetItem(data_list[index][2]))
            self.tablewidget.setItem(index,3,QTableWidgetItem(data_list[index][3]))

@staticmethod
    def getData():

        conn = sqlite3.connect('mydata.db')
        c = conn.cursor()
        cursor = c.execute('select * from mydata')

        data_list = []
        for row in cursor:
            temp_list = []
            temp_list.append(row[0])
            temp_list.append(row[1])
            temp_list.append(row[2])
            temp_list.append(row[3])
            data_list.append(temp_list)
        conn.close()
        return data_list
  • 新增按钮的功能设置,对话框的布局如下:
def addDef(self):

        # 新增的窗口,因为新增和修改共用一个对话框,所以需要在showDialog中参入参数表示这次点击的是新增按钮还是修改按钮
        self.showDialog(1)
    
    def showDialog(self, status ,website='', username='', passwd=''):

        self.dialog = QDialog(self)
        self.dialog.setWindowIcon(QIcon('icon.png'))
        if status == 1:
            self.dialog.setWindowTitle('新增')
        else:
            self.dialog.setWindowTitle('修改')

        # 创建一个group盒子
        group = QGroupBox(self.dialog)

        # 标签和输入框
        lb1 = QLabel('网站:', group)
        self.ed1 = QLineEdit(group)
        self.ed1.setText(website)
        lb2 = QLabel('账号:', group)
        self.ed2 = QLineEdit(group)
        self.ed2.setText(username)
        lb3 = QLabel('密码:', group)
        self.ed3 = QLineEdit(group)
        self.ed3.setText(passwd)

        # 创建确定和取消的按钮
        ok_button = QPushButton('确定', self.dialog)
        cancel_button = QPushButton('取消', self.dialog)

        # 创建一个垂直布局,将标签和按钮控件都添加到垂直布局里
        group_layout = QVBoxLayout()
        group_item = [lb1, self.ed1, lb2, self.ed2, lb3, self.ed3]
        for item in group_item:
            group_layout.addWidget(item)

        # 将垂直布局添加到groupbox中
        group.setLayout(group_layout)
        group.setFixedSize(group.sizeHint())

        # 创建一个水平布局,并将两个按钮添加到布局中
        button_layout = QHBoxLayout()
        button_layout.addWidget(ok_button)
        button_layout.addWidget(cancel_button)

        # 创建一个最外层的dialog垂直布局,将盒子和按钮布局加到这个布局中
        dialog_layout = QVBoxLayout()
        dialog_layout.addWidget(group)
        dialog_layout.addLayout(button_layout)

        # 设置这个对话框的布局
        self.dialog.setLayout(dialog_layout)
        self.dialog.setFixedSize(self.dialog.sizeHint())

        # 按传入的状态绑定确定按钮的功能
        if status == 1:
            ok_button.clicked.connect(self.addDialogAccept)
        else:
            ok_button.clicked.connect(self.editDialogAccept)

        # 默认选中ok按钮
        ok_button.setDefault(True)

        # 绑定取消按钮的功能
        cancel_button.clicked.connect(self.dialog.reject)

        self.dialog.exec_()
        return False
    
   # 新增对话框的ok按钮
   def addDialogAccept(self):

        # 如果每个输入项都不为空的表示输入正确
        if self.ed1.text() != '' and self.ed2.text() != '' and self.ed3.text() != '':
            # 关闭窗口
            self.dialog.close()
            # 在数据库中新增字段
            Tools.new_data(self.ed1.text(), self.ed2.text(), self.ed3.text())
            # 刷新表格
            self.flushTable()
            # 提示新增成功
            self.showHint('新增成功')
        else:
            self.showHint('必填项不能为空')
            
    # 提示对话框
    def showHint(self, message):

        hint_msg = QMessageBox()
        hint_msg.setText(message)
        hint_msg.addButton(QMessageBox.Ok)
        hint_msg.setWindowTitle("提示")
        hint_msg.exec_()
  • 新增的数据库操作
@staticmethod
    def addData(website, username, passwd):

        connect = sqlite3.connect('mydata.db')
        c = connect.cursor()
        command = "insert into mydata values(null,'%s','%s','%s')" % (website, username, passwd)
        print(command)
        c.execute(command)
        connect.commit()
        connect.close()
  • 修改按钮的功能设置,和新增共用一个对话框,只是在点击ok按钮时有所不同
def editDef(self):
        # 选中某行
        selected_row = self.tablewidget.selectedItems()

        # 如果当前选中的项数量为3时,表示只选取了一项
        if len(selected_row) == 3:

            # 获取该行行号
            edit_row = self.tablewidget.row(selected_row[0])

            # 记录当前选中项的id
            self.id = self.tablewidget.item(edit_row, 0).text()
            website = self.tablewidget.item(edit_row, 1).text()
            username = self.tablewidget.item(edit_row, 2).text()
            passwd = self.tablewidget.item(edit_row, 3).text()

            # 将获取到的选中行的数据赋予给修改窗口的方法,同时返回新数据
            self.showDialog(2, website, username, passwd)
        else:
            # 如果没有选中改行时,点击编辑,弹出提示框
            self.showHint("请选中一行进行编辑")

    def editDialogAccept(self):

        if self.ed1.text() != '' and self.ed2.text() != '' and self.ed3.text() != '':
            self.dialog.close()
            # 修改数据
            Tools.editData(self.id,self.ed1.text(), self.ed2.text(), self.ed3.text())
            self.flushTable()
            self.showHint('修改成功')
        else:
            self.showHint('必填项不能为空')
  • 修改的数据库操作
@staticmethod
    def editData(id, website, username, passwd):

        connect = sqlite3.connect('mydata.db')
        c = connect.cursor()
        print(1)
        command = "update mydata set website='%s',username='%s',passwd='%s' where id=%s" % (
        website, username, passwd, id)
        print(command)
        c.execute(command)
        connect.commit()
        connect.close()
  • 删除的按钮功能设置
def delDef(self):
        # 选中某行
        selected_row = self.tablewidget.selectedItems()
        if len(selected_row) == 3:

            del_row = self.tablewidget.row(selected_row[0])
            id = self.tablewidget.item(del_row, 0).text()
            print(id)
            # 如果返回值为True,表示点击了确定删除
            if self.delDialog() == True:
                Tools.delData(id)
                self.flushTable()

        else:
            # 如果没有选中改行时,点击编辑,弹出提示框
            self.showHint("请选中一行进行删除")
            
    # 布局和新增修改相差不大,不详细赘述
    def delDialog(self):
        delDialog = QDialog(self)
        delDialog.setWindowTitle(u'删除')
        group = QGroupBox('', delDialog)
        lb1 = QLabel(u'确定删除吗?删除后无法恢复')
        
        ok_button = QPushButton(u'确定', delDialog)
        cancel_button = QPushButton(u'取消', delDialog)

        ok_button.clicked.connect(delDialog.accept)
        ok_button.setDefault(True)
        cancel_button.clicked.connect(delDialog.reject)
        group_layout = QVBoxLayout()
        group_item = [lb1]
        for item in group_item:
            group_layout.addWidget(item)
        group.setLayout(group_layout)
        group.setFixedSize(group.sizeHint())

        button_layout = QHBoxLayout()
        button_layout.addWidget(ok_button)
        button_layout.addWidget(cancel_button)
        dialog_layout = QVBoxLayout()
        dialog_layout.addWidget(group)
        dialog_layout.addLayout(button_layout)
        delDialog.setLayout(dialog_layout)
        delDialog.setFixedSize(delDialog.sizeHint())

        # 当点击ok是,表示确定删除返回True
        if delDialog.exec_():
            return True
        # 否则返回False
        return False
  • 删除的数据库操作
@staticmethod
    def delData(id):
        print(33333)
        connect = sqlite3.connect('mydata.db')
        c = connect.cursor()
        print(1)
        command = "delete from mydata where id = %s" % id
        print(command)
        c.execute(command)
        connect.commit()
        connect.close()
打包程序

使用pyinstaller库将代码打包成exe可执行文件

安装pyinstaller库:

pip install pyinstaller

打包命令:

pyinstaller -F FirstApp.py --noconsole

最后就会在 dist目录下生成exe可执行文件

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-10-16,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 测试邦 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 背景
  • 最终效果
  • 使用框架
  • 代码设计
  • 打包程序
相关产品与服务
数据库
云数据库为企业提供了完善的关系型数据库、非关系型数据库、分析型数据库和数据库生态工具。您可以通过产品选择和组合搭建,轻松实现高可靠、高可用性、高性能等数据库需求。云数据库服务也可大幅减少您的运维工作量,更专注于业务发展,让企业一站式享受数据上云及分布式架构的技术红利!
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档