PyQT 跟我学做密码管理器(3)

PyQT 跟我学做密码管理器(2) ——实现基本功能

声明:本文借鉴https://blog.csdn.net/bigbennyguo/article/details/50755207 修改而来

前言

借鉴的文章是基于python2+pyqt4,本文是基于python3+pyqt5

环境

编辑器:Sublime Text3

操作系统:win10

Python3

所需要的库:主要是PyQT5,因为加了一点拓展功能,所以还有sqlite3,Image,pyinstaller

pip3 install pyqt5
pip3 install pyqt5-tools
pip3 install sqilte3
pip3 install Image
pip3 install pyinstaller

首先是pyqt5, 这个是我们的主要工具,用来做界面的,pyqt5-tools这个库主要是是在用QT Creator设计好界面之后,将ui文件转化为py文件;

sqlite3这个库可以安也可以不安,因为pyqt5里面有一个模块QtSql,它支持sqlite的操作;
Image这个库主要是用来处理一下图片资源,以及最后程序的图标的
pyinstaller 最后将程序转化为可执行的exe文件

功能实现

实现功能的话,其实最终是要用到数据库的,但是这一节先暂时不考虑数据库的事情

我们需要实现的是新建、编辑、删除三个action的功能,
分别对应着newAction_def、editAction_def和delAction_def三个函数。
但在实现它们之前,我们需要先实现一个新建和编辑功能都需要用到的编辑框,对应一个弹出编辑框的函数showDialog();
还需要实现一个报错的提示框,在用户没有选择任何一行却点击了修改或删除时提示用户”出错啦”,对应一个弹出提示框的函数showHint()。

首先说一下这个showDialog()

  def showDialog(self, ws = '', un = '', pw = '', url = ''):
        '''
        四个参数就是对应,Website,Username,Password,Url
        '''
	    edit_dialog = QDialog(self)                    #实例化一个Dialog
	    group = QGroupBox('Edit Info', edit_dialog)    #将一个GroupBox放入到Dialog

	    lbl_website = QLabel('Website:', group)        #为GroupBox添加Lable和lineedit
	    le_website = QLineEdit(group)
	    le_website.setText(ws)

	    lbl_username = QLabel('Username:', group)      #为GroupBox添加Lable和lineedit
	    le_username = QLineEdit(group)
	    le_username.setText(un)

	    lbl_password = QLabel('Password:', group)      #为GroupBox添加Lable和lineedit
	    le_password = QLineEdit(group)
	    le_password.setText(pw)

	    lbl_url = QLabel('Url:', group)                #为GroupBox添加Lable和lineedit
	    le_url = QLineEdit(group)
	    le_url.setText(url)

	    ok_button = QPushButton('OK', edit_dialog)         #为Dialog添加确定和取消按钮
	    cancel_button = QPushButton('CANCEL', edit_dialog)

	    ok_button.clicked.connect(edit_dialog.accept)         #为确定,取消按钮添加信号
	    ok_button.setDefault(True)
	    cancel_button.clicked.connect(edit_dialog.reject)

	    group_layout = QVBoxLayout()                       #把控件组合布局
	    group_item = [lbl_website, le_website,
	                  lbl_username, le_username,
	                  lbl_password, le_password,
	                  lbl_url, le_url]
	    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)
	    edit_dialog.setLayout(dialog_layout)
	    edit_dialog.setFixedSize(edit_dialog.sizeHint())

	    if edit_dialog.exec_():                            #点击OK出发事件  
	        website = le_website.text()
	        username = le_username.text()
	        password = le_password.text()
	        url = le_password.text()
	        return True, website, username, password, url
	    return False, None, None, None, None

只有我们输入数据之后点击‘ok’按钮,edit_dialog.exec()返回值才是True,点击‘cancel’会使它的返回值为False。这样的话,只有返回True,我们才使函数返回用户输入的一系列内容。

接下来就是showhint()

    def showHint(self):
        hint_msg = QMessageBox()
        hint_msg.setText('No selected row!')
        hint_msg.addButton(QMessageBox.Ok)
        hint_msg.exec_()

它就是一个报错的提示框,弹出一个提示窗口。

接着是三个功能函数,新建,编辑和删除

新建的时候,弹出Dialog,填写信息,根据返回值,得到填写的信息,决定是否填充表格

    def newAction_def(self):
        data = self.showDialog()                            #data是返回值,得到填写的信息
        if data[0]:                                         #data[0]是布尔值,由它判断数据返回是否正确
            self.current_row += 1
            self.grid.insertRow(self.current_row - 1)                    #在当前tableview行数的基础上再插入一行
            for i in range(4):
                new_item = QTableWidgetItem(data[i + 1])                #将每一个数据转化为QTableWidgetItem类型的
                self.grid.setItem(self.current_row - 1, i, new_item)    #将数据插入表格

编辑功能

首先判断是否有选中item,没有选中,直接弹窗提示
选中的话,将选中的那一行数据得到,传给Dialog,编辑完之后,再将填好的数据填充表格

def editAction_def(self):
        selected_row = self.grid.selectedItems()
        if selected_row:
            edit_row = self.grid.row(selected_row[0])
            old_data = []
            for i in range(4):
                old_data.append(self.grid.item(edit_row, i).text())
            new_data = self.showDialog(*old_data)
            if new_data[0]:
                for i in range(4):
                    new_item = QTableWidgetItem(new_data[i + 1])
                    self.grid.setItem(edit_row, i, new_item)
        else:
            self.showHint()

删除功能
首先判断是否有选中item,没有选中,直接弹窗提示
选中的话,删除这一行,并且更新当前行数

def delAction_def(self):
        selected_row = self.grid.selectedItems()
        if selected_row:
            del_row = self.grid.row(selected_row[0])
            self.grid.removeRow(del_row)
            self.current_row -= 1
        else:
            self.showHint()

小结

目前的基本功能实现了,增删改, 稍微缺少的功能是备份,因为目前数据没有存在任何地方,也没有实现备份功能,

所以程序每次运行都是空的,关闭程序后,数据就会消失,再次打开程序又是一片空白…

下一节加入数据库功能

目前完整代码如下:

# -*- coding: utf-8 -*-
# @Date     : 2018-12-17 16:50:23
# @Author   : Jimy_Fengqi (jmps515@163.com)
# @Link     : https://blog.csdn.net/qiqiyingse
# @Version  : V1.0
# @pyVersion: 3.6

import sys
from PyQt5.QtWidgets import *
from PyQt5.QtGui import QIcon, QFont
from PyQt5.QtCore import *


class PasswordManagerSystem(QMainWindow):

    def __init__(self):
        super(PasswordManagerSystem, self).__init__()
        self.initToolbar()
        self.initDB()
        self.initGrid()
        self.current_row = 0
        self.setGeometry(300, 300, 650, 300)
        self.setWindowTitle('密码管理器')
        self.setWindowIcon(QIcon('logo.jpg'))

    def initToolbar(self):
        newAction = QAction(QIcon('new.png'), 'New', self)
        editAction = QAction(QIcon('edit.png'), 'New', self)
        delAction = QAction(QIcon('del.png'), 'New', self)
        newAction.setShortcut('Ctrl+N')
        editAction.setShortcut('Ctrl+E')
        delAction.setShortcut('Delete')
        newAction.triggered.connect(self.newAction_def)
        editAction.triggered.connect(self.editAction_def)
        delAction.triggered.connect(self.delAction_def)
        self.tb_new = self.addToolBar('New')
        self.tb_edit = self.addToolBar('Edit')
        self.tb_del = self.addToolBar('Del')
        self.tb_new.addAction(newAction)
        self.tb_edit.addAction(editAction)
        self.tb_del.addAction(delAction)

    def initDB(self):
            pass

    def initGrid(self):
        self.grid = QTableWidget()
        self.setCentralWidget(self.grid)
        self.grid.setColumnCount(4)
        self.grid.setRowCount(0)
        column_width = [75, 150, 270, 150]
        for column in range(4):
            self.grid.setColumnWidth(column, column_width[column])
        headerlabels = ['Website', 'Username', 'Password', 'Url']
        self.grid.setHorizontalHeaderLabels(headerlabels)
        self.grid.setEditTriggers(QAbstractItemView.NoEditTriggers)
        self.grid.setSelectionBehavior(QAbstractItemView.SelectRows)



    def newAction_def(self):
        data = self.showDialog()
        if data[0]:
            self.current_row += 1
            self.grid.insertRow(self.current_row - 1)
            for i in range(4):
                new_item = QTableWidgetItem(data[i + 1])
                self.grid.setItem(self.current_row - 1, i, new_item)

    def editAction_def(self):
        selected_row = self.grid.selectedItems()
        if selected_row:
            edit_row = self.grid.row(selected_row[0])
            old_data = []
            for i in range(4):
                old_data.append(self.grid.item(edit_row, i).text())
            new_data = self.showDialog(*old_data)
            if new_data[0]:
                for i in range(4):
                    new_item = QTableWidgetItem(new_data[i + 1])
                    self.grid.setItem(edit_row, i, new_item)
        else:
            self.showHint()

 
    def delAction_def(self):
        selected_row = self.grid.selectedItems()
        if selected_row:
            del_row = self.grid.row(selected_row[0])
            self.grid.removeRow(del_row)
            self.current_row -= 1
        else:
            self.showHint()

    def showHint(self):
        hint_msg = QMessageBox()
        hint_msg.setText('No selected row!')
        hint_msg.addButton(QMessageBox.Ok)
        hint_msg.exec_()
    def showDialog(self, ws = '', un = '', pw = '', url = ''):
        '''
        四个参数就是对应,Website,Username,Password,Url
        '''
	    edit_dialog = QDialog(self)                    #实例化一个Dialog
	    group = QGroupBox('Edit Info', edit_dialog)    #将一个GroupBox放入到Dialog

	    lbl_website = QLabel('Website:', group)        #为GroupBox添加Lable和lineedit
	    le_website = QLineEdit(group)
	    le_website.setText(ws)

	    lbl_username = QLabel('Username:', group)      #为GroupBox添加Lable和lineedit
	    le_username = QLineEdit(group)
	    le_username.setText(un)

	    lbl_password = QLabel('Password:', group)      #为GroupBox添加Lable和lineedit
	    le_password = QLineEdit(group)
	    le_password.setText(pw)

	    lbl_url = QLabel('Url:', group)                #为GroupBox添加Lable和lineedit
	    le_url = QLineEdit(group)
	    le_url.setText(url)

	    ok_button = QPushButton('OK', edit_dialog)         #为Dialog添加确定和取消按钮
	    cancel_button = QPushButton('CANCEL', edit_dialog)

	    ok_button.clicked.connect(edit_dialog.accept)         #为确定,取消按钮添加信号
	    ok_button.setDefault(True)
	    cancel_button.clicked.connect(edit_dialog.reject)

	    group_layout = QVBoxLayout()                       #把控件组合布局
	    group_item = [lbl_website, le_website,
	                  lbl_username, le_username,
	                  lbl_password, le_password,
	                  lbl_url, le_url]
	    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)
	    edit_dialog.setLayout(dialog_layout)
	    edit_dialog.setFixedSize(edit_dialog.sizeHint())

	    if edit_dialog.exec_():                            #点击OK出发事件  
	        website = le_website.text()
	        username = le_username.text()
	        password = le_password.text()
	        url = le_password.text()
	        return True, website, username, password, url
	    return False, None, None, None, None



if __name__ == '__main__':
    app = QApplication(sys.argv)
    pwk = PasswordManagerSystem()
    pwk.show()
    sys.exit(app.exec_())

 

posted @ 2018-12-20 15:55  枫奇丶宛南  阅读(73)  评论(0)    收藏  举报