Использование PySide2.QtSql.QSqlRelationalTableModel()

Я решил использовать и изучить собственный класс Qt QtSql. Использование QSqlQuery() очень просто и очень похоже на SqlAlchemy.

Я пробовал использовать подход QTableView/Model, но с очень ограниченным успехом.

Мой справочный документ - это старая книга "Быстрое программирование графического интерфейса с помощью Python и Qt", но ее можно использовать.

После долгих экспериментов мне удалось частично, но моя текущая проблема немного сбивает с толку, и мои текущие поиски в Интернете не помогли (на сегодняшний день)

Форма отображает запрошенную информацию для первых двух записей, но не для последующих записей (последних двух). В базе четыре записи.

Разбивка базы данных

Основная таблица "tblRecipe" содержит ключ, имя рецепта, категорию и описание. Таблица поддержки "tblIngrediants" содержит от одного до нескольких ингредиентов для рецепта: поля: "ингредиент из последней таблицы в таблицу поиска, чтобы изменить целое число категории в "tblRecipe" на удобочитаемый текст. Я еще не пробовал включить эту таблицу.

Вопрос: Почему я получаю правильную информацию для первых 2 записей, а не для последних 2.

Я включил часть кода, имеющую отношение к моей проблеме.

import os
import sys
from PySide2.QtCore import *
from PySide2.QtGui import *
from PySide2.QtSql import *
from PySide2.QtWidgets import *
import qrc_resources


RECIPEKEY, RECIPENAME, RECIPECATEGORY, RECIPEDESCRIPTION = range(4)
INGREDIANTKEY, INGREDIANTDESCRIPTION, INGREDIANTRECIPEKEY, INGREDIANTQUANTITY = range(4)


class RecipeDlg(QDialog):

FIRST, PREV, NEXT, LAST = range(4)

def __init__(self, parent=None):
    super(RecipeDlg, self).__init__(parent)

    catLabel = QLabel("Category:")
    self.catEdit = QLineEdit()
    catLabel.setBuddy(self.catEdit)

    nameLabel = QLabel("Name:")
    self.nameEdit = QLineEdit()
    nameLabel.setBuddy(self.nameEdit)

    IngrediantLabel = QLabel("Ingrediants:")
    self.tvIngrediants = QTableView()   

    descriptionLabel = QLabel("Description:")
    self.descriptionEdit = QTextEdit()
    descriptionLabel.setBuddy(self.descriptionEdit)

    firstButton = QPushButton()
    firstButton.setIcon(QIcon(":/first.png"))
    prevButton = QPushButton()
    prevButton.setIcon(QIcon(":/prev.png"))
    nextButton = QPushButton()
    nextButton.setIcon(QIcon(":/next.png"))
    lastButton = QPushButton()
    lastButton.setIcon(QIcon(":/last.png"))
    addButton = QPushButton("&Add")
    addButton.setIcon(QIcon(":/add.png"))
    deleteButton = QPushButton("&Delete")
    deleteButton.setIcon(QIcon(":/delete.png"))
    quitButton = QPushButton("&Quit")
    quitButton.setIcon(QIcon(":/quit.png"))
    addButton.setFocusPolicy(Qt.NoFocus)
    deleteButton.setFocusPolicy(Qt.NoFocus)

    fieldLayout = QGridLayout()
    fieldLayout.addWidget(catLabel, 0, 0)
    fieldLayout.addWidget(self.catEdit, 0, 1, 1, 3)
    fieldLayout.addWidget(nameLabel, 1, 0)
    fieldLayout.addWidget(self.nameEdit, 1, 1)
    fieldLayout.addWidget(IngrediantLabel, 2, 0)
    fieldLayout.addWidget(self.tvIngrediants, 2, 1, 1, 3)
    fieldLayout.addWidget(descriptionLabel, 3, 0)
    fieldLayout.addWidget(self.descriptionEdit, 3, 1, 1, 3)
    navigationLayout = QHBoxLayout()
    navigationLayout.addWidget(firstButton)
    navigationLayout.addWidget(prevButton)
    navigationLayout.addWidget(nextButton)
    navigationLayout.addWidget(lastButton)
    fieldLayout.addLayout(navigationLayout, 4, 0, 1, 2)
    buttonLayout = QVBoxLayout()
    buttonLayout.addWidget(addButton)
    buttonLayout.addWidget(deleteButton)
    buttonLayout.addStretch()
    buttonLayout.addWidget(quitButton)
    layout = QHBoxLayout()
    layout.addLayout(fieldLayout)
    layout.addLayout(buttonLayout)
    self.setLayout(layout)

    self.model = QSqlTableModel(self)
    self.model.setTable("tblRecipe")
    self.model.setSort(RECIPECATEGORY, Qt.AscendingOrder)
    self.model.select()

    self.ingredModel = QSqlRelationalTableModel(self)
    self.ingredModel.setTable("tblIngrediants")
    self.ingredModel.setRelation(INGREDIANTKEY,
                                 QSqlRelation("tblRecipe", "recipeKey", "recipeName"))
    self.ingredModel.setHeaderData(INGREDIANTKEY, Qt.Horizontal, "id")
    self.ingredModel.setHeaderData(INGREDIANTDESCRIPTION, Qt.Horizontal,
                                   "Description")
    self.ingredModel.setHeaderData(INGREDIANTQUANTITY, Qt.Horizontal, "Quantity")
    self.ingredModel.select()

    self.tvIngrediants.setModel(self.ingredModel)       # connect to the model
    self.tvIngrediants.setSelectionMode(QTableView.SingleSelection)
    self.tvIngrediants.setSelectionBehavior(QTableView.SelectRows)
    self.tvIngrediants.setColumnHidden(INGREDIANTKEY, True)
    self.tvIngrediants.setColumnHidden(2, True)
    self.tvIngrediants.resizeColumnsToContents()

    self.mapper = QDataWidgetMapper(self)
    self.mapper.setSubmitPolicy(QDataWidgetMapper.ManualSubmit)
    self.mapper.setModel(self.model)
    self.mapper.setItemDelegate(QSqlRelationalDelegate(self))
    self.mapper.addMapping(self.catEdit, RECIPECATEGORY)
    self.mapper.addMapping(self.nameEdit, RECIPENAME)
    self.mapper.addMapping(self.descriptionEdit, RECIPEDESCRIPTION)
    #relationModel = self.ingredModel.relationModel(INGREDIANTRECIPEKEY)
    #self.tvIngrediants.setModel(relationModel)
    self.mapper.addMapping(self.tvIngrediants, INGREDIANTRECIPEKEY)
    self.mapper.toFirst()
    self.displayIngred()


    firstButton.clicked.connect(lambda: self.saveRecord(RecipeDlg.FIRST))
    prevButton.clicked.connect(lambda: self.saveRecord(RecipeDlg.PREV))
    nextButton.clicked.connect(lambda: self.saveRecord(RecipeDlg.NEXT))
    lastButton.clicked.connect(lambda: self.saveRecord(RecipeDlg.LAST))
    #addButton.clicked.connect(self.addRecord)
    #deleteButton.clicked.connect(self.deleteRecord)
    quitButton.clicked.connect(self.accept)

    self.setWindowTitle("Recipes")

def displayIngred(self):

    index = self.mapper.currentIndex()
    record = self.model.record(index)
    id = record.value("recipeKey")
    self.ingredModel.setFilter("ingrediantRecipeKey = {}".format(id))
    self.ingredModel.select()
    self.tvIngrediants.horizontalHeader().setVisible(
       self.ingredModel.rowCount() > 0)

def reject(self):
    self.accept()

def accept(self):
    self.mapper.submit()
    QDialog.accept(self)

def addRecord(self):
    pass

def deleteRecord(self):
    pass

def saveRecord(self, where):
    row = self.mapper.currentIndex()
    self.mapper.submit()
    if where == RecipeDlg.FIRST:
        row = 0

    elif where == RecipeDlg.PREV:
        row = 0 if row <= 1 else row - 1

    elif where == RecipeDlg.NEXT:
        row += 1
        if row >= self.model.rowCount():
            row = self.model.rowCount() - 1

    elif where == RecipeDlg.LAST:
        row = self.model.rowCount() - 1

    self.mapper.setCurrentIndex(row)
    self.displayIngred()



def main():
    app = QApplication(sys.argv)

filename = os.path.join(os.path.dirname(__file__), "Recipes.db")

db = QSqlDatabase.addDatabase("QSQLITE")
db.setDatabaseName(filename)
if not db.open():
    QMessageBox.warning(None, "Recipes",
                        "Database Error: {}".format(db.lastError().text()))
    sys.exit(1)

form = RecipeDlg()
form.show()
sys.exit(app.exec_())


main()

Изображения результата:

Запись 1

Запись 4, но ингредиенты не появляются


Поскольку Stackru, похоже, не разрешает передачу файлов, я включаю содержимое своего текстового файла SQL

BEGIN TRANSACTION;
CREATE TABLE IF NOT EXISTS `tblRecipe` (
    `recipeKey` INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT UNIQUE,
    `recipeName`    TEXT NOT NULL,
    `recipeCategory`    INTEGER NOT NULL,
    `recipeDescription` TEXT,
    FOREIGN KEY(`recipeCategory`) REFERENCES    `tblCategory`(`categoryKey`)
);
CREATE TABLE IF NOT EXISTS `tblIngrediants` (
    `ingrediantKey` INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT UNIQUE,
    `ingrediantDescription` TEXT NOT NULL,
    `ingrediantRecipeKey`   INTEGER NOT NULL,
    `ingrediantQuantity`    TEXT,
    FOREIGN KEY(`ingrediantRecipeKey`) REFERENCES `tblRecipe`(`recipeKey`)
);
CREATE TABLE IF NOT EXISTS `tblCategory` (
    `categoryKey`   INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT UNIQUE,
    `categoryName`  TEXT NOT NULL
);
COMMIT;

Я новичок в размещении на этом сайте, быстрый обзор справочного центра не дал мне решения.

0 ответов

Другие вопросы по тегам