Python PYQT使用QSqlRelationalTableModel和QtableView添加新记录

Python PYQT使用QSqlRelationalTableModel和QtableView添加新记录,python,pyqt,pyqt5,postgresql-9.3,Python,Pyqt,Pyqt5,Postgresql 9.3,我试图向我的QtableView添加一个新行,从而向Postgresql数据库添加一条记录。这样做的目的是添加记录,并允许用户以如下形式就地编辑: 添加行似乎很顺利,但当我试图编辑它时,垂直标题显示一个感叹号和两个字段,我已经为它们设置了数据 问题是,如何添加行进行就地编辑?如果该行已经存在,则编辑它没有问题 from PyQt5.QtCore import * from PyQt5.QtGui import * from PyQt5.QtSql import * from PyQt5.Qt

我试图向我的QtableView添加一个新行,从而向Postgresql数据库添加一条记录。这样做的目的是添加记录,并允许用户以如下形式就地编辑:

添加行似乎很顺利,但当我试图编辑它时,垂直标题显示一个感叹号和两个字段,我已经为它们设置了数据

问题是,如何添加行进行就地编辑?如果该行已经存在,则编辑它没有问题

from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtSql import *
from PyQt5.QtWidgets import *
import sys
from datetime import datetime, timedelta, time

#form modules
from main import *


class Main(QMainWindow):

    def __init__(self, parent=None):
        QMainWindow.__init__(self, parent)
        self.ui = Ui_Nextock()
        self.ui.setupUi(self)
        currentdate = QDate.currentDate()
        self.ui.weekending.setDate(currentdate.addDays(6-currentdate.dayOfWeek()))
        #self.ui.weekending.setDate(QDate(2017, 6, 10))

        self.emp_model = QSqlRelationalTableModel(self)
        self.emp_model.setTable('employees')
        self.emp_model.setSort(int(self.emp_model.fieldIndex("empid")), Qt.AscendingOrder)
        self.emp_model.setRelation(self.emp_model.fieldIndex("department"), QSqlRelation('departments', 'department', 'department'))
        self.emp_model.setFilter("termination_date IS NULL")
        self.emp_model.select()
        self.ui.department.setModel(self.emp_model.relationModel(self.emp_model.fieldIndex("department")))
        self.emp_mapper = QDataWidgetMapper(self)
        self.emp_mapper.setSubmitPolicy(QDataWidgetMapper.ManualSubmit)
        self.emp_mapper.setModel(self.emp_model)
        self.emp_mapper.addMapping(self.ui.title, self.emp_model.fieldIndex("salutation"))
        self.emp_mapper.addMapping(self.ui.first_name, self.emp_model.fieldIndex("first_name"))
        self.emp_mapper.addMapping(self.ui.last_name, self.emp_model.fieldIndex("surname"))
        self.emp_mapper.addMapping(self.ui.address, self.emp_model.fieldIndex("Address"))
        self.emp_mapper.addMapping(self.ui.email, self.emp_model.fieldIndex('email'))
        self.emp_mapper.addMapping(self.ui.phone, self.emp_model.fieldIndex('phone'))
        self.emp_mapper.addMapping(self.ui.mobile, self.emp_model.fieldIndex('mobile'))
        self.emp_mapper.addMapping(self.ui.birthdate, self.emp_model.fieldIndex('birth_date'))
        self.emp_mapper.addMapping(self.ui.start_date, self.emp_model.fieldIndex('start_date'))
        self.emp_mapper.addMapping(self.ui.contracted_hours, self.emp_model.fieldIndex('contracted_hours'))
        self.emp_mapper.addMapping(self.ui.payrate, self.emp_model.fieldIndex('pay_rate'))
        self.emp_mapper.addMapping(self.ui.username, self.emp_model.fieldIndex('loginid'))
        self.emp_mapper.addMapping(self.ui.password, self.emp_model.fieldIndex('pwd'))
        self.emp_mapper.addMapping(self.ui.department, self.emp_model.fieldIndex('department'))
        self.emp_mapper.setItemDelegate(QSqlRelationalDelegate(self.emp_mapper))
        self.emp_mapper.toFirst()

        self.hours_model = Tc_relational_model(self)
        self.hours_model.setTable('emphours')
        self.hours_model.setSort(self.hours_model.fieldIndex('id'), Qt.AscendingOrder)
        self.hours_model.setRelation(self.hours_model.fieldIndex("department"), QSqlRelation('departments', 'department', 'department'))
        self.hours_model.setRelation(self.hours_model.fieldIndex("paytype"), QSqlRelation('pay_types', 'pay_type', 'pay_type'))
        self.hours_model.select()
        self.hours_view = self.ui.emp_hours
        self.hours_view.setModel(self.hours_model)
        self.hours_view.setItemDelegate(QSqlRelationalDelegate(self.hours_view))
        self.hours_view.setColumnHidden(self.hours_model.fieldIndex('id'), True)
        self.hours_view.setColumnHidden(self.hours_model.fieldIndex('empyear'), True)
        self.hours_view.setColumnHidden(self.hours_model.fieldIndex('empweek'), True)
        self.hours_view.setColumnHidden(self.hours_model.fieldIndex('empmonth'), True)
        self.hours_view.setEditTriggers(QAbstractItemView.AllEditTriggers)
        self.hours_model.dataChanged.connect(self.dta_chng)

        self.ui.weekending.dateChanged.connect(lambda: self.record_changed(self.emp_mapper.currentIndex()))
        self.ui.new_line.clicked.connect(self.new_line)


        self.ui.current_index.setText('Record ' + str(self.emp_mapper.currentIndex()+1) + ' of ' + str(self.emp_model.rowCount()) + ' records')

    def dta_chng(self):
        print(self.hours_model.lastError().text())


    def new_line(self):
        row =  self.hours_model.rowCount()
        self.hours_model.insertRow(row)
        self.idx_empid = QModelIndex(self.hours_model.index(row, self.hours_model.fieldIndex('empid')))
        self.hours_model.setData(self.idx_empid, int(self.ui.emp_id.text()), Qt.EditRole)
        self.idx_weekending = QModelIndex(self.hours_model.index(row, self.hours_model.fieldIndex('weekending')))
        #self.hours_model.setData(self.idx_weekending, self.ui.weekending.date(), Qt.EditRole)
        print('In new_line')


    def record_changed(self, index):
        self.emp_mapper.submit()
        if index >= 0:
            total_hours = timedelta(0)
            the_id = self.emp_model.record(index).value('empid')
            self.hours_model.setFilter("empid = '{0}' and weekending = '{1}'".format(the_id,
                                                                                     self.ui.weekending.date().toString(Qt.ISODate)))
            self.ui.name_label.setText(self.emp_model.record(index).value('surname')
                                       + ", " + self.emp_model.record(index).value('first_name'))
            self.ui.terminationdate.setText(self.emp_model.record(index).value('termination_date').toString("dd/MM/yyyy"))
            self.ui.emp_id.setText(str(self.emp_model.record(index).value('empid')))

            for row in range(self.hours_model.rowCount()):
                #elapsed = self.data(self.index(index.row(), 9)).toPyDateTime() - self.data(self.index(index.row(), 8)).toPyDateTime()
                elapsed = self.hours_model.index(row, 9).data().toPyDateTime() - self.hours_model.index(row, 8).data().toPyDateTime()
                if elapsed.total_seconds() > 0:
                    total_hours += elapsed

            self.ui.total_hours.setText(str(total_hours))

        else:
            self.hours_model.setFilter("empid = -1")


class Tc_relational_model(QSqlRelationalTableModel):
    def __init__(self, parent=None):
        super(Tc_relational_model, self).__init__(parent)
        self.setEditStrategy(QSqlRelationalTableModel.OnFieldChange)
        self.setTable("emphours")
        self.select()

    def columnCount(self, parent=QtCore.QModelIndex()):
        return super(Tc_relational_model, self).columnCount()+1

    def data(self, index, role=QtCore.Qt.DisplayRole):
        if role == QtCore.Qt.DisplayRole and index.column()==10:
            if self.data(self.index(index.row(), 9)) is not None and self.data(self.index(index.row(), 8)) is not None:
                elapsed = self.data(self.index(index.row(), 9)).toPyDateTime() - self.data(self.index(index.row(), 8)).toPyDateTime()
            else:
                elapsed = timedelta()
            if elapsed.total_seconds() < 0:
                elapsed = ''
            else:
                elapsed = str(elapsed)
            return elapsed

        if index.column() > 10:
            index = self.index(index.row(), index.column()-1)

        return super(Tc_relational_model, self).data(index, role)

    def headerData(self, section, orientation, role=QtCore.Qt.DisplayRole):
        if section==10 and orientation==QtCore.Qt.Horizontal and role==QtCore.Qt.DisplayRole:
            return 'Elapsed time'
        if section > 10 and orientation==QtCore.Qt.Horizontal:
            section -= 1
        return super(Tc_relational_model, self).headerData(section, orientation, role)

    def flags(self, index):
        if index.column()==10:
            return QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled
        return QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsEditable

    def setData(self, index, data, role):
        if index.column() > 10:
            index = self.index(index.row(), index.column()-1)
        return super(Tc_relational_model, self).setData(index, data, role)





if __name__=="__main__":
    app=QApplication(sys.argv)
    pword = 'pword'
    dbase = 'db'
    server = 'server'
    user = 'dave'
    db = QSqlDatabase.addDatabase("QPSQL");
    db.setHostName(server)
    db.setDatabaseName(dbase)
    db.setUserName(user)
    db.setPassword(pword)
    if (db.open()==False):
        QMessageBox.critical(None, "Database Error", db.lastError().text())

    myapp = Main()
    myapp.show()
    sys.exit(app.exec_())
从PyQt5.QtCore导入*
从PyQt5.QtGui导入*
从PyQt5.QtSql导入*
从PyQt5.QtWidgets导入*
导入系统
从datetime导入datetime、timedelta、time
#表单模块
从主要进口*
类主(QMainWindow):
def uuu init uuu(self,parent=None):
QMainWindow.\uuuu init\uuuuu(自,父)
self.ui=ui_Nextock()
self.ui.setupUi(self)
currentdate=QDate.currentdate()
self.ui.weekending.setDate(currentdate.addDays(6-currentdate.dayOfWeek())
#self.ui.weekending.setDate(QDate(2017年6月10日))
self.emp_model=QSqlRelationalTableModel(self)
self.emp_model.setable('employees')
self.emp_model.setSort(int(self.emp_model.fieldIndex(“empid”)),Qt.AscendingOrder)
self.emp_model.setRelation(self.emp_model.fieldIndex(“department”)、QSqlRelation(“departments”、“department”、“department”))
self.emp_model.setFilter(“终止日期为空”)
self.emp_model.select()
self.ui.department.setModel(self.emp_model.relationModel(self.emp_model.fieldIndex(“department”))
self.emp_mapper=QDataWidgetMapper(self)
self.emp_mapper.setSubmitPolicy(QDataWidgetMapper.ManualSubmit)
self.emp_映射器.setModel(self.emp_模型)
self.emp_mapper.addMapping(self.ui.title,self.emp_model.fieldIndex(“称呼”))
self.emp\u mapper.addMapping(self.ui.first\u name,self.emp\u model.fieldIndex(“first\u name”))
self.emp\u mapper.addMapping(self.ui.last\u name,self.emp\u model.fieldIndex(“姓氏”))
self.emp_mapper.addMapping(self.ui.address,self.emp_model.fieldIndex(“地址”))
self.emp_mapper.addMapping(self.ui.email,self.emp_model.fieldIndex('email'))
self.emp_mapper.addMapping(self.ui.phone,self.emp_model.fieldIndex('phone'))
self.emp_mapper.addMapping(self.ui.mobile,self.emp_model.fieldIndex('mobile'))
self.emp\u mapper.addMapping(self.ui.birthdate,self.emp\u model.fieldIndex('birthdate'))
self.emp\u mapper.addMapping(self.ui.start\u date,self.emp\u model.fieldIndex('start\u date'))
self.emp\u mapper.addMapping(self.ui.contracted\u hours,self.emp\u model.fieldIndex('contracted\u hours'))
self.emp\u mapper.addMapping(self.ui.payrate,self.emp\u model.fieldIndex('pay\u rate'))
self.emp_mapper.addMapping(self.ui.username,self.emp_model.fieldIndex('loginid'))
self.emp_mapper.addMapping(self.ui.password,self.emp_model.fieldIndex('pwd'))
self.emp_mapper.addMapping(self.ui.department,self.emp_model.fieldIndex('department'))
self.emp_映射器.setItemDelegate(QSqlRelationalDelegate(self.emp_映射器))
self.emp_mapper.toFirst()
self.hours\u model=Tc\u relational\u model(self)
self.hours\u model.setable('emphours'))
self.hours\u model.setSort(self.hours\u model.fieldIndex('id'),Qt.AscendingOrder)
self.hours\u model.setRelation(self.hours\u model.fieldIndex(“部门”)、QSqlRelation(“部门”、“部门”、“部门”))
self.hours\u model.setRelation(self.hours\u model.fieldIndex(“paytype”)、QSqlRelation(“pay\u type”、“pay\u type”、“pay\u type”))
self.hours\u model.select()
self.hours\u view=self.ui.emp\u hours
self.hours\u view.setModel(self.hours\u模型)
self.hours_view.setItemDelegate(QSqlRelationalDelegate(self.hours_view))
self.hours\u view.setColumnHidden(self.hours\u model.fieldIndex('id'),True)
self.hours\u view.setColumnHidden(self.hours\u model.fieldIndex('empyer'),True)
self.hours\u view.setColumnHidden(self.hours\u model.fieldIndex('empweek'),True)
self.hours\u view.setColumnHidden(self.hours\u model.fieldIndex('empmonth'),True)
self.hours\u view.setEditTriggers(QAbstractItemView.AllEditTriggers)
self.hours\u model.dataChanged.connect(self.dta\u chng)
self.ui.weekending.dateChanged.connect(lambda:self.record\u changed(self.emp\u mapper.currentIndex()))
self.ui.new\u-line.clicked.connect(self.new\u-line)
self.ui.current_index.setText('Record'+str(self.emp_mapper.currentIndex()+1)+'of'+str(self.emp_model.rowCount())+'records'))
def dta_chng(自身):
打印(self.hours\u model.lastError().text())
def新管路(自身):
row=self.hours\u model.rowCount()
self.hours\u model.insertRow(行)
self.idx\u empid=QModelIndex(self.hours\u model.index(行,self.hours\u model.fieldIndex('empid'))
self.hours\u model.setData(self.idx\u empid,int(self.ui.emp\u id.text()),Qt.EditRole)
self.idx_weekending=QModelIndex(self.hours_model.index(行,self.hours_model.fieldIndex('weekending'))
#self.hours\u model.setData(self.idx\u weekending,self.ui.weekending.date(),Qt.EditRole)
打印('在新行中')
def记录_已更改(自身,索引):
self.emp_mapper.submit()
如果索引>=0:
总时数=时间增量(0)
\u id=self.emp\u model.record(index.value('empid'))
self.hours_model.setFilter(“empid='{0}'和weekending='{1}'”.format(the_id,
self.ui.weekending.date().toString(Qt.ISODate)))
self.ui.name\u label.setText(self.emp\u model.record(index.value('姓氏'))
+“,”+self.emp_model.record(index.value('first_name'))
self.ui.terminationdate.setText(self.emp\u model.record(index.value('termination\u date')).toSt
def new_line(self):
    row =  self.hours_model.rowCount()
    record = self.hours_model.record()
    record.setGenerated('id', False)
    record.setValue('empid', self.ui.emp_id.text())
    record.setValue('weekending', self.ui.weekending.date())
    record.setValue('department', self.ui.department.currentText())
    record.setValue('pay_type', 'Regular')
    record.setValue('starttime', QDateTime.currentDateTime())
    record.setValue('endtime', QDateTime.currentDateTime())
    self.hours_model.insertRecord(row, record)
    self.hours_view.edit(QModelIndex(self.hours_model.index(row, self.hours_model.fieldIndex('department'))))