如何将选定的行数据从 QSqlTableModel tableview 复制到所需的 Qlineedit 输入小部件中?

How to copy selected row data from QSqlTableModel tableview into reqired Qlineedit input widgets?

示例图片:

下面是我的示例代码:

from PyQt5 import QtCore, QtGui, QtWidgets, QtSql
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtSql import *
from PyQt5 import uic
import sys
import sqlite3


class UI(QMainWindow):
    def __init__(self):
        super(UI, self).__init__()
        uic.loadUi("tableview.ui", self)
        self.show()

        db = QSqlDatabase.addDatabase('QSQLITE')
        db.setDatabaseName('book.db')
        db.open()

        self.model = QtSql.QSqlTableModel(self)
        self.model.setTable("card")
        self.model.select()
        self.tableView.setModel(self.model)

        #self.view_msa()

        self.pushButton.clicked.connect(self.edit_items)

    def edit_view(self):

        self.editWindow = QtWidgets.QWidget()
        self.editWindow.resize(300, 300)
        self.editWindow.setWindowTitle("Edit Window")
        self.editWindow.setWindowModality(Qt.ApplicationModal)
        
        self.update = QtWidgets.QPushButton(self.editWindow)
        self.update.setGeometry(QtCore.QRect(60, 150, 75, 23))
        self.update.setObjectName("update")
        self.widget = QtWidgets.QWidget(self.editWindow)
        self.widget.setGeometry(QtCore.QRect(60, 60, 201, 74))
        self.widget.setObjectName("widget")
        self.formLayout = QtWidgets.QFormLayout(self.widget)
        self.formLayout.setContentsMargins(0, 0, 0, 0)
        self.formLayout.setObjectName("formLayout")
        self.label = QtWidgets.QLabel(self.widget)
        self.label.setObjectName("label")
        self.formLayout.setWidget(0, QtWidgets.QFormLayout.LabelRole, self.label)
        self.name_line = QtWidgets.QLineEdit(self.widget)
        self.name_line.setObjectName("name_line")
        self.formLayout.setWidget(0, QtWidgets.QFormLayout.FieldRole, self.name_line)
        self.label_2 = QtWidgets.QLabel(self.widget)
        self.label_2.setObjectName("label_2")
        self.formLayout.setWidget(1, QtWidgets.QFormLayout.LabelRole, self.label_2)
        self.age_line = QtWidgets.QLineEdit(self.widget)
        self.age_line.setObjectName("age_line")
        self.formLayout.setWidget(1, QtWidgets.QFormLayout.FieldRole, self.age_line)
        self.label_3 = QtWidgets.QLabel(self.widget)
        self.label_3.setObjectName("label_3")
        self.formLayout.setWidget(2, QtWidgets.QFormLayout.LabelRole, self.label_3)
        self.address_line = QtWidgets.QLineEdit(self.widget)
        self.address_line.setObjectName("address_line")
        self.formLayout.setWidget(2, QtWidgets.QFormLayout.FieldRole, self.address_line)

        self.update.setText("Update")
        self.label.setText("Name")
        self.label_2.setText("Age")
        self.label_3.setText("Address")

        self.name_line.setReadOnly(True)
        
        self.editWindow.show()

    def edit_items(self):
        index = (self.tableView.selectionModel().currentIndex())
        id_us = (self.tableView.model().data(index))
        print(str(id_us))
        self.edit_view()
        
app = QApplication(sys.argv)
window = UI()
app.exec_()

我正在使用:self.model = QtSql.QSqlTableModel、Qtableview、3 个 Lineedit 输入小部件和 2 个 QPushbutton。我的 SQLite3 数据库有 3 列,分别是“姓名、年龄(整数值)和性别” 我的问题是: 如果我 select tableview 中的一行 3 个项目应该作为名称、年龄和地址复制到它们各自的 lineedit 输入小部件中,那怎么可能做到这一点。名称 Editline 是只读的,然后如果按下更新按钮,QSqlTableModel 应该使用名称 lineedit 的引用更新(名称 lineedit 是只读的)。

您需要访问您感兴趣的每一列的各个索引。这可以通过调用 index.sibling 或在知道当前行后立即通过简单的 model.index(row, column) 来完成。

然后,您可以使用 QDialog,它比设置了 window 模态的 QWidget 更好,因为您可以使用它的 exec_() 方法来“阻止”该功能,直到对话框出现已关闭。

在下面的示例中,我将更新按钮连接到 dialog.accept() 插槽,以便仅在单击按钮时更新数据,否则如果对话框被取消(通过按 Esc 键或关闭它) 没有应用任何更改。

如您所见,我没有设置任何实例属性(就像您对 self.editWindow 所做的那样),因为它们的引用仅在函数范围内很重要,并且您将要每次将它们设置为属性时重新创建对话框。

class UI(QMainWindow):
    def __init__(self):
        # ...
        self.pushButton.clicked.connect(self.edit_items)

    def edit_items(self):
        if not self.model.rowCount():
            return
        index = self.tableView.currentIndex()
        if index.isValid():
            row = index.row()
        else:
            row = 0

        dialog = QtWidgets.QDialog()
        dialog.setWindowTitle("Edit Window")
        layout = QtWidgets.QVBoxLayout(dialog)

        formLayout = QtWidgets.QFormLayout()
        layout.addLayout(formLayout)

        name_line = QtWidgets.QLineEdit(self.model.index(row, 0).data())
        formLayout.addRow('Name', name_line)
        name_line.setReadOnly(True)

        age_edit = QtWidgets.QSpinBox()
        formLayout.addRow('Age', age_edit)
        age_edit.setFocus()
        age_edit.setValue(self.model.index(row, 1).data())

        genders = 'M', 'F'
        gender_combo = QtWidgets.QComboBox()
        formLayout.addRow('Gender', gender_combo)
        gender_combo.addItems(genders)
        gender = self.model.index(row, 2).data()
        if gender and gender.upper() in genders:
            gender_combo.setCurrentIndex(genders.index(gender.upper()))
        else:
            gender_combo.setCurrentIndex(-1)

        updateButton = QtWidgets.QPushButton('Update')
        layout.addWidget(updateButton)
        updateButton.clicked.connect(dialog.accept)

        if not dialog.exec_():
            return

        self.model.setData(self.model.index(row, 1), age_edit.value(), 
            QtCore.Qt.EditRole)
        if gender_combo.currentIndex() >= 0:
            self.model.setData(self.model.index(row, 2), 
                gender_combo.currentText(), QtCore.Qt.EditRole)
        # submit all changes to the database
        self.model.submitAll()

注意:避免覆盖现有的 class 属性,就像您对 self.update 所做的那样。