【问题标题】:build master/detail form using pyqt and qtsql使用 pyqt 和 qtsql 构建主/详细信息表单
【发布时间】:2016-03-16 18:11:57
【问题描述】:

编辑:重新发布新代码和明确的问题: 在下面的代码中,您可以正确添加和保存,问题是: 我需要做同样的事情,但没有在行更改时将数据提交到数据库,我需要能够添加新的联系人记录(主)并将电话插入表(详细信息)而不提交我插入的每条记录并仅在单击保存时提交

-------------老问题-------

我想使用 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_())

【问题讨论】:

  • 如果您将鼠标指针悬停在反对票图标上,您将看到一个工具提示:此问题未显示任何研究成果;不清楚或没用。这可能就是为什么有人对你投了反对票。
  • 谢谢汤姆,我会完善它

标签: python qt pyqt qtsql qsqltablemodel


【解决方案1】:

您需要在新行中设置外键列“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())

【讨论】:

  • 这被标记为 VLQ,但我不确定......这个问题和这对我来说都没有任何意义,我也看不出它们之间有任何联系。乍一看,由于没有问题陈述,这看起来像是一个随机猜测。
  • 我的问题可能不清楚,我已经按照你说的做了,并添加了代码以在单击某些联系人时查看手机并保存新手机,一切正常,除非我添加新联系人我可以'然后添加新手机,直到我关闭表单并重新打开它,否则我必须将手机模型重新链接到联系人模型并用数据填充它并提交数据 OnRowChange
  • 这正是我所做的,只要当前的联系人记录已经保存,它就可以工作,但如果我只是插入一个新联系人,手机模型 setData 将无法工作,直到我用数据重新填充它并再次设置与联系人模型的关系,这意味着我必须保存每个电话记录并且不能按需保存,如果你没有我的意思,我可以提交一些完整的代码给你看
  • 我认为你想要的是手动提交。将两个模型 self.contacts_model.setEditStrategy(QSqlTableModel.OnManualSubmit)EditStrategy 更改为 QSqlTableModel::OnManualSubmit。更多信息请参考documentation
猜你喜欢
  • 1970-01-01
  • 2010-12-22
  • 2015-06-03
  • 1970-01-01
  • 2023-04-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多