-1

編集:新しいコードと明確な質問で再投稿: 以下のコードでは、適切に追加して保存できます。質問は:同じことをする必要がありますが、行の変更時にデータベースにデータを送信せずに、新しい連絡先を追加できる必要がありますレコード (マスター) と電話をテーブル (詳細) に挿入し、レコードごとに送信せずに挿入し、[保存] をクリックしたときにのみ送信します

--------------昔の質問 -------------------

QtSqlとPyQtを使用してマスター/詳細データを表示するフォームを作成したいので、以下のコードは私がやりたいことのサンプルです。連絡先の下に新しい電話を挿入して保存できるようにする必要があります

「PythonとQtを使用した高速GUIプログラミング」の本を読みましたが、その方法が見つからなかったので、この質問を完全な実例とともに投稿しました。これは、希望どおりに動作するように変更する必要があります

編集:実際、なぜ反対票を投じたのかわかりませんか?質問は明確ではありませんか?

import sys
from PySide.QtGui import *
from PySide.QtSql import *


class MainWidget(QWidget):

    def __init__(self):
        QWidget.__init__(self)
        self.setWindowTitle("Address Book Example")
        self.initUI()
        db = QSqlDatabase.addDatabase("QSQLITE")
        db.setDatabaseName("addressbook.db")
        ok = db.open()

        self.contacts_model = QSqlTableModel()
        self.contacts_model.setTable('contacts')
        self.contacts_model.setEditStrategy(QSqlTableModel.OnFieldChange)
        self.contacts_model.select()

        self.phones_model = QSqlRelationalTableModel()
        self.phones_model.setTable('phones')
        self.phones_model.setEditStrategy(QSqlTableModel.OnRowChange)
        self.phones_model.setRelation(1, QSqlRelation('contacts', 'id', 'full_name'))
        self.phones_model.select()

        self.conatacts_mapper = QDataWidgetMapper()
        self.conatacts_mapper.setModel(self.contacts_model)
        self.conatacts_mapper.addMapping(self.txtFullName, 1)
        self.conatacts_mapper.addMapping(self.txtAddress, 2)
        self.conatacts_mapper.toFirst()
        self.record_changed()

        self.tblPhones.setModel(self.phones_model)
        # self.tblPhones.setColumnHidden(0, True)
        # self.tblPhones.setColumnHidden(1, True)

        self.btnNext.clicked.connect(self.conatacts_mapper.toNext)
        self.btnPrev.clicked.connect(self.conatacts_mapper.toPrevious)
        self.btnAdd.clicked.connect(self.add_record)
        self.btSave.clicked.connect(self.save)
        self.btNew.clicked.connect(self.new_contact)
        self.conatacts_mapper.currentIndexChanged.connect(self.record_changed)

    def add_record(self):
        if self.phones_model.rowCount() == 0:
            index = self.conatacts_mapper.currentIndex()
            self.conatacts_mapper.submit()
            self.conatacts_mapper.setCurrentIndex(index)
            self.prepare_sub()
        row = self.phones_model.rowCount()
        self.phones_model.insertRow(row)
        index = self.phones_model.index(row, 1)
        self.tblPhones.setCurrentIndex(index)
        self.tblPhones.edit(index)
        self.phones_model.setData(self.phones_model.index(self.phones_model.rowCount() - 1, 1),
                                  self.contacts_model.record(self.conatacts_mapper.currentIndex()).value('id'))

    def record_changed(self):
        self.phones_model.setFilter("contact_id = {}".format(self.conatacts_mapper.currentIndex()+1))

    def save(self):
        self.contacts_model.submitAll()
        self.phones_model.submitAll()
        self.conatacts_mapper.submit()

    def new_contact(self):
        self.contacts_model.insertRow(self.contacts_model.rowCount())
        self.conatacts_mapper.setCurrentIndex(self.contacts_model.rowCount() - 1)

    def prepare_sub(self):
        self.phones_model.setTable('phones')
        self.phones_model.setRelation(1, QSqlRelation('contacts', 'id', 'full_name'))
        self.phones_model.select()
        self.phones_model.setFilter('contact_id=%s' % self.contacts_model.record(self.conatacts_mapper.currentIndex()).value('id'))

    def initUI(self):
        main_layout = QHBoxLayout()
        right_layout = QVBoxLayout()
        left_layout = QVBoxLayout()

        main_layout.addLayout(right_layout)
        main_layout.addLayout(left_layout)

        name_label = QLabel("Full Name")
        self.txtFullName = QLineEdit()
        address_label = QLabel("Address")
        self.txtAddress = QLineEdit()
        phones_label = QLabel("Phone Numbers")
        self.tblPhones = QTableView()

        right_layout.addWidget(name_label)
        right_layout.addWidget(self.txtFullName)
        right_layout.addWidget(address_label)
        right_layout.addWidget(self.txtAddress)

        right_layout.addWidget(phones_label)
        right_layout.addWidget(self.tblPhones)

        self.btnPrev = QPushButton("Previous")
        self.btnNext = QPushButton("Next")
        self.btnAdd = QPushButton("Add")
        self.btSave = QPushButton('Save')
        self.btNew = QPushButton('New')

        left_layout.addWidget(self.btNew)
        left_layout.addWidget(self.btnPrev)
        left_layout.addWidget(self.btnNext)
        left_layout.addStretch(1)
        left_layout.addWidget(self.btnAdd)
        left_layout.addWidget(self.btSave)

        self.setLayout(main_layout)

if __name__ == '__main__':
    app = QApplication(sys.argv)
    w = MainWidget()
    w.show()
    sys.exit(app.exec_())
4

1 に答える 1

0

新しい行の外部キー列「contact_id」の値を設定する必要があります。

次のようにコードを更新しました。

1-連絡先IDを保持する新しいフィールドを追加し、レイアウトに追加します

    id_label = QLabel("Id")
    self.txtId = QLineEdit()
    self.txtId.setReadOnly(True)
    #....

    right_layout.addWidget(id_label)
    right_layout.addWidget(self.txtId)

2- マッピングを更新して txtId を埋める

    self.conatacts_mapper.addMapping(self.txtId, 0)

3- add_record メソッドを更新して、電話モデルの contact_id を埋める

 def add_record(self):
    indexModel = self.phones_model.rowCount()
    self.phones_model.insertRow(indexModel)
    self.phones_model.setData(self.phones_model.index(indexModel,1),self.txtId.text())
于 2015-12-13T16:30:45.293 に答える