4 июля 2012 г.

Пример использования QSqlRelationalTableModel в PySide

QSqlRelationalTableModel используется PySide для работы с таблицами которые имеют поле foreign key. Для работы с foreign key достаточно использовать метод setRelation с параметрами состоящими из номера поля, таблицы от куда подставляют значения, поле идентификатора и поле  значений идентификатора. Также при использовании QSqlRelationalTableModel есть возможность использовать QComboBox в связанных полях в QTableView. Для этого нужно использовать метод setItemDelegate класса QTableView. Пример.
# -*- coding: utf-8 -*-
"""
Created on Tue Jul 03 16:48:15 2012

@author: Amin
"""
from PySide import QtGui, QtSql, QtCore
import sys


class Form(QtGui.QWidget):
    def __init__(self, parent=None):
        # Создаем кнопки, поля, гриды для работы с данными
        super(Form, self).__init__(parent)
        self.label = QtGui.QLabel(self)
        self.lineEdit = QtGui.QLineEdit(self)
        self.label_2 = QtGui.QLabel(self)
        self.comboBox = QtGui.QComboBox(self)
        self.pushButton = QtGui.QPushButton(self)
        self.pushButton_2 = QtGui.QPushButton(self)
        self.pushButton_3 = QtGui.QPushButton(self)
        self.pushButton_4 = QtGui.QPushButton(self)
        self.pushButton_5 = QtGui.QPushButton(self)
        self.pushButton_6 = QtGui.QPushButton(self)
        self.label_3 = QtGui.QLabel(self)
        self.label_4 = QtGui.QLabel(self)
        self.tableView = QtGui.QTableView(self)
        self.tableView_2 = QtGui.QTableView(self)    
        self.label.setText(u'Ученик')
        self.label_2.setText(u'Класс')
        self.label_3.setText(u'Список учеников')
        self.label_4.setText(u'Список классов')
        self.pushButton.setText(u'Сохранить ученика')
        self.pushButton_2.setText(u'Новый ученик')
        self.pushButton_3.setText(u'Предижущая')
        self.pushButton_4.setText(u'Следующая')
        self.pushButton_5.setText(u'Добавить класс')
        self.pushButton_6.setText(u'Сохранить класс')
        #Размещаем элемениы управления по сетке
        self.gridLayout = QtGui.QGridLayout(self)
        self.gridLayout.setContentsMargins(5, 5, 5, 5)
        self.gridLayout.addWidget(self.tableView_2, 2, 5, 1, 7)
        self.gridLayout.addWidget(self.label, 0, 0, 1, 1)
        self.gridLayout.addWidget(self.lineEdit, 0, 1, 1, 1)
        self.gridLayout.addWidget(self.label_2, 0, 2, 1, 1)
        self.gridLayout.addWidget(self.comboBox, 0, 3, 1, 1)
        self.gridLayout.addWidget(self.pushButton, 0, 5, 1, 1)
        self.gridLayout.addWidget(self.pushButton_2, 0, 4, 1, 1)
        self.gridLayout.addWidget(self.pushButton_3, 0, 6, 1, 1)
        self.gridLayout.addWidget(self.pushButton_4, 0, 7, 1, 1)
        self.gridLayout.addWidget(self.pushButton_5, 3, 5, 1, 1)
        self.gridLayout.addWidget(self.pushButton_6, 3, 6, 1, 1)
        self.gridLayout.addWidget(self.label_3, 1, 0, 1, 1)
        self.gridLayout.addWidget(self.label_4, 1, 5, 1, 1)
        self.gridLayout.addWidget(self.tableView, 2, 0, 1, 5)
        
        self.mapdata()
    
    def mapdata(self):
        #Простая таблица со списком классов
        self.formmodel = QtSql.QSqlTableModel()
        self.formmodel.setTable('forms')
        self.tableView_2.setModel(self.formmodel)
        self.formmodel.select()
        
        #Модель с foreign полем
        self.studmodel = QtSql.QSqlRelationalTableModel()
        self.studmodel.setTable('studients')
        self.studmodel.setRelation(2, QtSql.QSqlRelation('forms', 'id', 'name'))
        
        #Таблица с foreign полем
        self.tableView.setModel(self.studmodel)
        self.tableView.setItemDelegate(QtSql.QSqlRelationalDelegate(self.tableView))
        self.studmodel.select()
        
        self.mapper = QtGui.QDataWidgetMapper(self)
        self.mapper.setModel(self.studmodel)
        
        #ComboBox с foreign полем
        self.mapper.setItemDelegate(QtSql.QSqlRelationalDelegate(self))
        self.mapper.addMapping(self.lineEdit, 1)
        self.rellmap = self.studmodel.relationModel(2)
        self.comboBox.setModel(self.rellmap)
        self.comboBox.setModelColumn(self.rellmap.fieldIndex('name'))
        self.mapper.addMapping(self.comboBox, 2)
        
        self.mapper.toFirst()         

        self.connect(self.pushButton, QtCore.SIGNAL('clicked()'), self.studmodel.submit)                          
        self.connect(self.pushButton_2, QtCore.SIGNAL('clicked()'), self.new_std)
        self.connect(self.pushButton_3, QtCore.SIGNAL('clicked()'), self.mapper.toPrevious)
        self.connect(self.pushButton_4, QtCore.SIGNAL('clicked()'), self.mapper.toNext)
        self.connect(self.pushButton_5, QtCore.SIGNAL('clicked()'), self.new_form)
        self.connect(self.pushButton_6, QtCore.SIGNAL('clicked()'), self.formmodel.submit)
        
    def new_std(self):
        row = self.studmodel.rowCount()
        self.mapper.submit()
        self.studmodel.insertRow(row)
        self.mapper.setCurrentIndex(row)
        self.lineEdit.setFocus()

    def new_form(self):
        row = self.formmodel.rowCount()
        self.formmodel.insertRow(row)
        

#приложение
main=QtGui.QApplication(sys.argv)
#подключение база
dbase = QtSql.QSqlDatabase.addDatabase('QSQLITE')
#файл базы
dbase.setDatabaseName('my_db.sqlite')
dbase.open()

query=QtSql.QSqlQuery()
#Создаем базу
query.exec_('''CREATE TABLE forms
                (id integer PRIMARY KEY AUTOINCREMENT UNIQUE NOT NULL,
                name VARCHAR(9));''')
query.exec_('''CREATE TABLE studients
                (id integer PRIMARY KEY AUTOINCREMENT UNIQUE NOT NULL,
                name VARCHAR(255),
                form_id integer,
                FOREIGN KEY (form_id ) REFERENCES forms);''')

        
my_win = Form()
my_win.show()
sys.exit(main.exec_())        
Вот результат работы.