Пишу программу для хранения учётных записей.
Пока что модель программы выглядит вот так:
Накручивать функционал я буду потом. Сейчас главное отработать общую механику.
Хочу обратить внимание на то, что две левые “колонки” - это QListWidget. Поле с паролем буду менять на поле со звёздочками. База данных записана в виде списка с тройной вложенностью.
Сейчас база загружается с файла “basa.py”, а сохраняется в “basa3.pkl” - такая схема чисто для отработки механики.
В дальнейшем собираюсь шифровать базу данных и использовать мастер-пароль. Однако пока не разбирался с этим (уже предчувствую, как мне будут писать, что я изначально неправильно сохраняю базу данных…).
В общем, если кому интересно, то можете принять участие в разработке.
На данный момент у меня есть вопрос о поведении QListWidget.
Суть проблемы. Выбираю категорию, в листе учёток появляется список учёток. Выбираю учётку, в полях карточки учётной записи появляются данные. Если я меняю учётную запись, то данные в карточке меняются. Всё хорошо. Однако, если поменять категорию, то индекс учётки не сбрасывается (пытаюсь понять, как его всё-таки сбросить), поэтому карточка начинает лагать: в свои поля она начинает вставлять список учёток.
Код программы:
# Python 3. PyQt4 # -*- coding: utf-8 -*- import sys import pickle import res.basa as basa from PyQt4 import QtGui, QtCore '''F_R = open('res/basa3.pkl', 'rb') db = pickle.load(F_R)''' db = basa.db db_кат = basa.db[0] кат_index = 0 уч_index = 0 # ГРАФИКА class Window(QtGui.QWidget): def __init__(self, parent=None): QtGui.QWidget.__init__(self, parent) self.setMinimumSize(450, 400) # Миниамльная ширина и высота окна self.resize(600, 400) # шир / выс окна, работает парал. с setMinimumSize self.setWindowTitle('Хранение учётных записей') # Заголовок self.setWindowIcon(QtGui.QIcon('res\icon.png')) # Иконка # БЛОК СОЗДАНИЯ FRAME self.frame_1 = QtGui.QFrame() self.frame_1.setFrameShape(1) self.frame_1_lay = QtGui.QGridLayout(self.frame_1) # БЛОК СОЗДАНИЯ LABEL self.lbl_кат = QtGui.QLabel('Категории:') self.lbl_уч = QtGui.QLabel('Учётки:') self.lbl = QtGui.QLabel() self.lbl_адрес = QtGui.QLabel('Адрес:') self.lbl_логин = QtGui.QLabel('Логин:') self.lbl_пароль = QtGui.QLabel('Пароль:') self.lbl_почта = QtGui.QLabel('Почта:') self.lbl_имя = QtGui.QLabel('Имя:') self.lbl_фмл = QtGui.QLabel('Фамилия:') self.lbl_дата_откр = QtGui.QLabel('Открыто:') self.lbl_дата_закр = QtGui.QLabel('Закрыто:') # БЛОК СОЗДАНИЯ ПОЛЕЙ self.pole_кат = QtGui.QLineEdit() self.pole_кат.setPlaceholderText('Добавить категорию') self.pole_уч = QtGui.QLineEdit() self.pole_уч.setPlaceholderText('Добавить учётку') self.pole_адрес = QtGui.QLineEdit() self.pole_адрес.textChanged.connect(self.on_st_0) self.pole_логин = QtGui.QLineEdit() self.pole_логин.textChanged.connect(self.on_st_1) self.pole_пароль = QtGui.QLineEdit() self.pole_пароль.textChanged.connect(self.on_st_2) self.pole_почта = QtGui.QLineEdit() self.pole_почта.textChanged.connect(self.on_st_3) self.pole_имя = QtGui.QLineEdit() self.pole_имя.textChanged.connect(self.on_st_4) self.pole_фмл = QtGui.QLineEdit() self.pole_фмл.textChanged.connect(self.on_st_5) self.pole_дата_откр = QtGui.QLineEdit() self.pole_дата_откр.textChanged.connect(self.on_st_6) self.pole_дата_закр = QtGui.QLineEdit() self.pole_дата_закр.textChanged.connect(self.on_st_7) # БЛОК СОЗДАНИЯ КНОПОК self.button_prnt = QtGui.QPushButton('Print db') self.button_prnt.clicked.connect(self.on_prnt) self.button_кат_плюс = QtGui.QPushButton('+') self.button_кат_плюс.clicked.connect(self.on_kat_plus) self.button_кат_минус = QtGui.QPushButton('-') self.button_кат_минус.clicked.connect(self.on_kat_minus) self.button_уч_плюс = QtGui.QPushButton('+') self.button_уч_плюс.clicked.connect(self.on_uch_plus) self.button_уч_минус = QtGui.QPushButton('-') self.button_уч_минус.clicked.connect(self.on_uch_minus) self.button_copy = QtGui.QPushButton('Копировать') self.button_плюс = QtGui.QPushButton('+') self.button_минус = QtGui.QPushButton('-') self.button_адрес = QtGui.QPushButton('Адрес') self.button_логин = QtGui.QPushButton('Логин') self.button_пароль = QtGui.QPushButton('Пароль') self.button_почта = QtGui.QPushButton('Почта') # Q_LIST_WIDGET self.listWidget_кат = QtGui.QListWidget() self.listWidget_кат.addItems(db_кат) self.listWidget_кат.setFixedWidth(150) self.listWidget_кат.currentRowChanged.connect(self.on_kat) # изм номера строки категории self.listWidget_кат.currentRowChanged.connect(self.on_st_clear) # self.listWidget_кат.currentRowChanged.connect(self.on_kat_crnt) # очистка строк учётки self.listWidget_кат.itemDoubleClicked.connect(self.on_kat_edit) # редактирование имени категории self.listWidget_уч = QtGui.QListWidget() self.listWidget_уч.setFixedWidth(150) self.listWidget_уч.currentRowChanged.connect(self.on_uch) # БЛОК РАЗМЕТКИ self.grid_os = QtGui.QGridLayout() # создание сетки self.grid_os.setSpacing(5) self.grid_os.addWidget(self.lbl_кат, 1,0,1,2) self.grid_os.addWidget(self.lbl_уч, 1,2,1,2) self.grid_os.addWidget(self.button_copy, 1, 4) self.grid_os.addWidget(self.listWidget_кат, 2,0,1,2) self.grid_os.addWidget(self.listWidget_уч, 2,2,1,2) self.grid = QtGui.QGridLayout() # создание сетки self.grid.addWidget(self.frame_1,0,0) # Фрейм 1 self.frame_1_lay.addWidget(self.button_адрес,1,0) self.frame_1_lay.addWidget(self.button_логин,2,0) self.frame_1_lay.addWidget(self.button_пароль,3,0) self.frame_1_lay.addWidget(self.button_почта,4,0) # self.frame_1_lay.addWidget(self.lbl_адрес,1,0,1,3) # self.frame_1_lay.addWidget(self.lbl_логин,2,0,1,3) # self.frame_1_lay.addWidget(self.lbl_пароль,3,0,1,3) # self.frame_1_lay.addWidget(self.lbl_почта,4,0,1,3) self.frame_1_lay.addWidget(self.lbl_имя,5,0,1,3) self.frame_1_lay.addWidget(self.lbl_фмл,6,0,1,3) self.frame_1_lay.addWidget(self.lbl_дата_откр,7,0,1,3) self.frame_1_lay.addWidget(self.lbl_дата_закр,8,0,1,3) self.frame_1_lay.addWidget(self.pole_адрес,1,3,1,3) self.frame_1_lay.addWidget(self.pole_логин,2,3,1,3) self.frame_1_lay.addWidget(self.pole_пароль,3,3,1,3) self.frame_1_lay.addWidget(self.pole_почта,4,3,1,3) self.frame_1_lay.addWidget(self.pole_имя,5,3,1,3) self.frame_1_lay.addWidget(self.pole_фмл,6,3,1,3) self.frame_1_lay.addWidget(self.pole_дата_откр,7,3,1,3) self.frame_1_lay.addWidget(self.pole_дата_закр,8,3,1,3) self.grid_os.addWidget(self.pole_кат, 3,0,1,2) self.grid_os.addWidget(self.pole_уч, 3,2,1,2) self.grid_os.addWidget(self.button_кат_плюс, 4,0) self.grid_os.addWidget(self.button_кат_минус, 4,1) self.grid_os.addWidget(self.button_уч_плюс, 4,2) self.grid_os.addWidget(self.button_уч_минус, 4,3) self.grid_os.addWidget(self.button_prnt, 4, 6) self.grid_os.addLayout(self.grid,2,4,1,6) self.setLayout(self.grid_os) # установка рабочей области def basa_save(self): # сохранить базу данных F_W = open('res/basa3.pkl', 'wb') pickle.dump(db,F_W) F_W.close() def on_kat(self): # изм категории кат_index = self.listWidget_кат.currentRow() # принимает номер строки уч_index = None print('кат_index = ',кат_index) уч_lst = db[кат_index+1][0] # print('уч_lst = ',уч_lst) self.listWidget_уч.clear() self.listWidget_уч.addItems(уч_lst) # print('db = ',db) return кат_index def on_uch(self): # изм учётки кат_index = self.listWidget_кат.currentRow() уч_index = self.listWidget_уч.currentRow() # принимает номер строки if уч_index == None: уч_index = None else: уч_index = self.listWidget_уч.currentRow() self.pole_адрес.setText(db[кат_index+1][уч_index+1][0]) self.pole_логин.setText(db[кат_index+1][уч_index+1][1]) self.pole_пароль.setText(db[кат_index+1][уч_index+1][2]) self.pole_почта.setText(db[кат_index+1][уч_index+1][3]) self.pole_имя.setText(db[кат_index+1][уч_index+1][4]) self.pole_фмл.setText(db[кат_index+1][уч_index+1][5]) self.pole_дата_откр.setText(db[кат_index+1][уч_index+1][6]) self.pole_дата_закр.setText(db[кат_index+1][уч_index+1][7]) print('кат_index = ',кат_index) print('уч_index = ',уч_index) def on_kat_plus(self): # добавить категорию кат_index = self.listWidget_кат.currentRow() a = self.pole_кат.text() # имя категории if a: self.listWidget_кат.insertItem(кат_index+1, a) db_кат.insert(кат_index+1, a) # к списку категорий db.insert(кат_index+2, [[]]) # пустой список учёток Window().basa_save() self.pole_кат.clear() print('db плюс = ',db) def on_kat_minus(self): # удалить категорию кат_index = self.listWidget_кат.currentRow() self.listWidget_кат.takeItem(кат_index) del db[0][кат_index] del db[кат_index+1] Window().basa_save() print('кат_index = ',кат_index) print('db минус = ',db) def on_uch_plus(self): # добавить учётку кат_index = self.listWidget_кат.currentRow() уч_index = self.listWidget_уч.currentRow() b = self.pole_уч.text() # имя учётки if b: self.listWidget_уч.addItem(b) self.listWidget_уч.sortItems() db[кат_index+1][0].append(b) # к списку учёток db[кат_index+1][0].sort() db[кат_index+1][1:].sort() db[кат_index+1].append(['','','','','','','','']) print('db плюс = ') Window().prnt(db) print('db[кат_index+1][уч_index+1][0] = ',db[кат_index+1][уч_index+1][0]) self.pole_уч.clear() Window().basa_save() def on_uch_minus(self): # удалить учётку кат_index = self.listWidget_кат.currentRow() уч_index = self.listWidget_уч.currentRow() self.listWidget_уч.takeItem(уч_index) del db[кат_index+1][0][уч_index] del db[кат_index+1][уч_index+1] Window().prnt(db) Window().basa_save() print('db минус = ') def on_kat_crnt(self): 1 def on_kat_edit(self): кат_index = self.listWidget_кат.currentRow() self.listWidget_кат.editItem(0) # ЗАПОЛНЕНИЕ УЧЁТКИ def on_st_0(self): кат_index = self.listWidget_кат.currentRow() уч_index = self.listWidget_уч.currentRow() db[кат_index+1][уч_index+1][0] = self.pole_адрес.text() Window().basa_save() def on_st_1(self): кат_index = self.listWidget_кат.currentRow() уч_index = self.listWidget_уч.currentRow() db[кат_index+1][уч_index+1][1] = self.pole_логин.text() Window().basa_save() def on_st_2(self): кат_index = self.listWidget_кат.currentRow() уч_index = self.listWidget_уч.currentRow() db[кат_index+1][уч_index+1][2] = self.pole_пароль.text() Window().basa_save() def on_st_3(self): кат_index = self.listWidget_кат.currentRow() уч_index = self.listWidget_уч.currentRow() db[кат_index+1][уч_index+1][3] = self.pole_почта.text() Window().basa_save() def on_st_4(self): кат_index = self.listWidget_кат.currentRow() уч_index = self.listWidget_уч.currentRow() db[кат_index+1][уч_index+1][4] = self.pole_имя.text() Window().basa_save() def on_st_5(self): кат_index = self.listWidget_кат.currentRow() уч_index = self.listWidget_уч.currentRow() db[кат_index+1][уч_index+1][5] = self.pole_фмл.text() Window().basa_save() def on_st_6(self): кат_index = self.listWidget_кат.currentRow() уч_index = self.listWidget_уч.currentRow() db[кат_index+1][уч_index+1][6] = self.pole_дата_откр.text() Window().basa_save() def on_st_7(self): кат_index = self.listWidget_кат.currentRow() уч_index = self.listWidget_уч.currentRow() db[кат_index+1][уч_index+1][7] = self.pole_дата_закр.text() print('db хар = ') Window().basa_save() def on_st_clear(self): # очистка полей учётки '''self.pole_адрес.setText('') self.pole_логин.setText('') self.pole_пароль.setText('') self.pole_почта.setText('') self.pole_имя.setText('') self.pole_фмл.setText('') self.pole_дата_откр.setText('') self.pole_дата_закр.setText('')''' def on_prnt(self, A): Window().prnt(db) def prnt(self, A): for i in A: print(i) # КОНЕЦ if __name__ == "__main__": app = QtGui.QApplication(sys.argv) window = Window() window.show() sys.exit(app.exec_())
Файл базы данных basa.py
db = [['АААА','ББББ'], [['А - учёт 0','А - учёт 1'], ['aaa0.ru','egir0','123456','egir@ex.ru','','','12.01.2017',''], ['aaa1.ru','egir1','123456','egir@ex.ru','','','12.01.2017','']], [['Б - учёт 0','Б - учёт 1'], ['bbb0.ru','fvr','123456','nch@ex.ru','','','15.08.2013',''], ['bbb1.ru','sadw','123456','gfhd@ex.ru','','','19.03.2016','']]]