Форум сайта python.su
from PyQt4 import QtGui, QtSql, QtCore import os.path class window1(QtGui.QWidget): def __init__(self, titletext): QtGui.QWidget.__init__(self) self.resize(800, 600) self.setWindowTitle(titletext) self.OpenOrCreateDB() #подключаемся к БД или создаём новую БД self.layout1 = QtGui.QVBoxLayout() # создаём контейнер для расположения в нём других виджетов self.setLayout(self.layout1) # назначаем его основным для нашей формы (окна) self.model1 = QtSql.QSqlTableModel(None, self.DB) #создаём модель для хранения строк из БД, указываем с какой БД ей работать self.model1.setTable("table1") # указываем нужную таблицу из БД self.model1.setEditStrategy(QtSql.QSqlTableModel.OnManualSubmit) # данные сохраняются в БД посредством этой модели, только по команде self.model1.select() # запускаем комаду select, для выборки всех записей из указанной таблицы БД self.tableView1 = QtGui.QTableView() # создаём грид (таблицу для отображения данных из модели) для формы self.tableView1.setModel(self.model1) # указываем гриду из какой модели брать данные для отображения self.tableView1.setEditTriggers(QtGui.QAbstractItemView.NoEditTriggers) #таким зашибенным способом запрещается редактирование ячеек пользователем self.layout1.addWidget(self.tableView1) self.btnNew = QtGui.QPushButton("Добавить новую строку в БД") #создаём кнопку self.btnNew.clicked.connect(self.btnNewClicked) # связываем событие нажатия на кнопку с обработчиком для этого события self.layout1.addWidget(self.btnNew) # добавляем её в контейнер на форме self.btnEdit = QtGui.QPushButton("Редактировать текущую строку БД") self.btnEdit.clicked.connect(self.btnEditClicked) self.layout1.addWidget(self.btnEdit) def btnNewClicked(self): self.OpenEditWindow("NEW") def btnEditClicked(self): self.OpenEditWindow("EDIT") def OpenEditWindow(self, NewOrEdit): secondwindow = window2(NewOrEdit, self.tableView1.currentIndex().row()) result = secondwindow.exec() # если здесь использовать show, то окно не будет модальным! Т.е. из него можно будет спокойно перейти в другое окно. print (result) def OpenOrCreateDB(self): #создаём объект для работы с БД self.DB = QtSql.QSqlDatabase.addDatabase("QSQLITE", "Base") self.DB.setDatabaseName("./SQLiteBase/Lesson16DB.db") existDB = os.path.exists("./SQLiteBase/Lesson16DB.db") #проверяем физичиское наличие БД if not existDB: print ("БД не существует. Попытка создать новую БД...") if not self.DB.open(): #попытка открыть БД (она же создание новой БД, если файла БД не существует) print("БД не открылась! Ошибка:", self.DB.lastError().text()) else: #подключение к БД произошло. Если при этом была создана новая БД, нужно создать в ней таблицы if not existDB: self.CreateStructureOfNewDB() def CreateStructureOfNewDB(self): query = QtSql.QSqlQuery(self.DB) querytext = ("CREATE TABLE table1 (" "id INTEGER, " "fam VARCHAR(20), " "im VARCHAR(20), " "ot VARCHAR(20), " "dr DATE, " "pol VARCHAR(1), " "gorod VARCHAR(20)" ")") #print (querytext) errors = 0 tmp = query.exec(querytext) if not tmp: errors = errors + 1 querytext = ("CREATE TABLE spisok1 (" "id INTEGER, " "text VARCHAR(20)" ")") tmp = query.exec(querytext) if not tmp: errors = errors + 1 return tmp if errors > 1: print ("БД не создана! Ошибка: ", self.DB.lastError().text()) return False else: return True class window2(QtGui.QDialog): # создаём окно типа Диалог def __init__(self, NewOrEdit, currentIndex_): QtGui.QDialog.__init__(self) self.mapper = QtGui.QDataWidgetMapper() #маппер для связки данных из модели с контролами self.mapper.setModel(windowmain.model1) #связываем его с моделью данных из объекта windowmain self.mapper.setSubmitPolicy(QtGui.QDataWidgetMapper.ManualSubmit) #обновление данных в модели будет произведено только по команде tmpstr = NewOrEdit if NewOrEdit == "NEW": tmpstr = "Добавление новой записи в БД" Record = windowmain.model1.record() #создаём объект типа рекорд для добавления строки в модель windowmain.model1.insertRecord(-1, Record) #insertRow использовать не стоит! Он не поддерживает связанные таблицы! self.mapper.toLast() #маппер тоже передвигаем к последней записи! elif NewOrEdit == "EDIT": tmpstr = "Редактирование записи" self.setWindowTitle(tmpstr) #self.setWindowModality(QtCore.Qt.WindowModal) self.layout2 = QtGui.QHBoxLayout() self.layout2_1 = QtGui.QVBoxLayout() self.layout2.addLayout(self.layout2_1) self.layout2_2 = QtGui.QVBoxLayout() self.layout2.addLayout(self.layout2_2) self.layout2_3 = QtGui.QHBoxLayout() self.layout2.addLayout(self.layout2_3) self.setLayout(self.layout2) Alignment = QtCore.Qt.AlignTop self.id_label = QtGui.QLabel("Номер") self.id_ = QtGui.QLineEdit() self.layout2_1.addWidget(self.id_label, alignment = Alignment) self.layout2_2.addWidget(self.id_, alignment = Alignment) self.mapper.addMapping(self.id_, windowmain.model1.fieldIndex("id")) #связываем контрол id_ с полем id из маппера, который передаст значение в модель, которая передаст в БД (вот такие тут все передасты!) self.fam_label = QtGui.QLabel("Фамилия") self.fam_ = QtGui.QLineEdit() self.layout2_1.addWidget(self.fam_label, alignment = Alignment) self.layout2_2.addWidget(self.fam_, alignment = Alignment) self.mapper.addMapping(self.fam_, windowmain.model1.fieldIndex("fam")) self.im_label = QtGui.QLabel("Имя") self.im_ = QtGui.QLineEdit() self.layout2_1.addWidget(self.im_label, alignment = Alignment) self.layout2_2.addWidget(self.im_, alignment = Alignment) self.mapper.addMapping(self.im_, windowmain.model1.fieldIndex("im")) self.ot_label = QtGui.QLabel("Отчество") self.ot_ = QtGui.QLineEdit() self.layout2_1.addWidget(self.ot_label, alignment = Alignment) self.layout2_2.addWidget(self.ot_, alignment = Alignment) self.mapper.addMapping(self.ot_, windowmain.model1.fieldIndex("ot")) self.dr_label = QtGui.QLabel("Дата рождения") self.dr_ = QtGui.QLineEdit() self.layout2_1.addWidget(self.dr_label, alignment = Alignment) self.layout2_2.addWidget(self.dr_, alignment = Alignment) self.mapper.addMapping(self.dr_, windowmain.model1.fieldIndex("dr")) self.pol_label = QtGui.QLabel("Пол") self.pol_ = QtGui.QLineEdit() self.layout2_1.addWidget(self.pol_label, alignment = Alignment) self.layout2_2.addWidget(self.pol_, alignment = Alignment) self.mapper.addMapping(self.pol_, windowmain.model1.fieldIndex("pol")) self.gorod_label = QtGui.QLabel("Город") self.gorod_ = QtGui.QComboBox() #создаём модель для комбобокса self.gorodModel = QtSql.QSqlTableModel(None, windowmain.DB) self.gorodModel.setTable("spisok1") self.gorodModel.select() self.gorod_.setModel(self.gorodModel) self.gorod_.setModelColumn(1) self.layout2_1.addWidget(self.gorod_label, alignment = Alignment) self.layout2_2.addWidget(self.gorod_, alignment = Alignment) self.mapper.addMapping(self.gorod_, windowmain.model1.fieldIndex("gorod")) self.btnSave = QtGui.QPushButton("Запомнить") self.btnSave.clicked.connect(self.SaveData) self.layout2_3.addWidget(self.btnSave, alignment = QtCore.Qt.AlignRight) self.btnCancel = QtGui.QPushButton("Отменить") self.btnCancel.clicked.connect(self.Cancel) self.layout2_3.addWidget(self.btnCancel, alignment = QtCore.Qt.AlignRight) if NewOrEdit == "EDIT": self.mapper.setCurrentIndex(currentIndex_) # Этот способ выбора текущей строки из модели нужно проерить. Что будет, если данные в модели будут отсортированы? def SaveData(self): self.mapper.submit() #сохраняем изменения в модели windowmain.model1.submitAll() # а теперь сохраняем изменения из модели в БД self.close() def Cancel(self): windowmain.model1.revertAll() #отменяем изменения в модели. Иначе вновь добавленная строка останется. self.close() #закрываем окно if __name__ == "__main__": import sys app = QtGui.QApplication(sys.argv) windowmain = window1("Первое окно") windowmain.show() sys.exit(app.exec_())
Офлайн