Search code examples
pythonpyqt4qtableview

How do i append data in a QTableView by clicking a button?


I am using a QTableView to show content from my database. The program has 2 QLineEdits: self.nameSlot and self.amountSlot. I also has self.toDay which is a QdateEdit. When i insert new data to the database using self.applyButton, it works as required but the data is not appended to the QTableView. How do i solve that problem? This is my code

import sys
from PyQt4 import QtGui, QtCore, QtSql
from Printer import PrintView
from database import DatabaseInfo
import Sky2


class Sky(QtGui.QMainWindow, Sky2.Ui_MainWindow):
    def __init__(self):
        QtGui.QWidget.__init__(self)
        self.setupUi(self)

        self.database = DatabaseInfo()
        self.database.setup()

        self.applyButton.clicked.connect(self.new_client)

        self.toDay.setMinimumDate(QtCore.QDate.currentDate())
        self.toDay.setMaximumDate(QtCore.QDate.currentDate())

        self.tableView.resizeColumnsToContents()
        self.tableView.horizontalHeader().setVisible(True)
        self.tableView.setShowGrid(False)
        self.tableView.setSortingEnabled(True)
        # failed to use sort
        # self.tableView.sortByColumn(self, 2, QtCore.Qt.SortOrder(0))
        database = QtSql.QSqlDatabase.addDatabase('QSQLITE')
        database.setDatabaseName('database.db')
        database.open()
        self.table_model = QtSql.QSqlQueryModel()
        self.table_model.setQuery("SELECT * FROM Clients ")
        self.tableView.setModel(self.table_model)
        self.table_model.setHeaderData(0, QtCore.Qt.Horizontal, "Name")
        self.table_model.setHeaderData(1, QtCore.Qt.Horizontal, "Amount")
        self.table_model.setHeaderData(2, QtCore.Qt.Horizontal, "Date")

    def new_client(self):
        name = self.nameSlot.text()
        amount = self.amountSlot.text()
        date = self.toDay.text()
        self.database.add_client(name, amount, date)
        self.table_model.layoutChanged.emit()
        self.tableView.setModel(self.table_model)
        # print('success')

   def keyPressEvent(self, event):
        if event.key() == QtCore.Qt.Key_P:
            self.printing()

    def printing(self):
        printer = QtGui.QPrinter(QtGui.QPrinter.ScreenResolution)
        dialog = QtGui.QPrintPreviewDialog(printer)
        view = PrintView()
        view.setModel(self.tableView.model())
        dialog.paintRequested.connect(view.print_)
        dialog.exec_()


def main():
    app = QtGui.QApplication(sys.argv)
    gui = Sky()
    gui.show()
    app.exec_()
if __name__ == '__main__':
    main()

Solution

  • QSqlQueryModel is not notified of changes so if you want to get new information you must request it through setQuery()

    def new_client(self):
        name = self.nameSlot.text()
        amount = self.amountSlot.text()
        date = self.toDay.text()
        self.database.add_client(name, amount, date)
        self.table_model.setQuery("SELECT * FROM Clients ")
    

    If you are going to work with a table, you could use QSqlTableModel in a simple and elective way, and you could add elements through QSqlRecord() and the insertRecord() method, with this method the model is notified because the order is done by the model.

    class Sky(QtGui.QMainWindow, Sky2.Ui_MainWindow):
        def __init__(self):
            QtGui.QMainWindow.__init__(self)
            self.setupUi(self)
            self.applyButton.clicked.connect(self.new_client)
    
            self.toDay.setMinimumDate(QtCore.QDate.currentDate())
            self.toDay.setMaximumDate(QtCore.QDate.currentDate())
    
            self.tableView.resizeColumnsToContents()
            self.tableView.horizontalHeader().setVisible(True)
            self.tableView.setShowGrid(False)
            self.tableView.setSortingEnabled(True)
            # failed to use sort
            # self.tableView.sortByColumn(self, 2, QtCore.Qt.SortOrder(0))
            self.database = QtSql.QSqlDatabase.addDatabase('QSQLITE')
            self.database.setDatabaseName('database.db')
            if not self.database.open():
                self.close()
            self.table_model = QtSql.QSqlTableModel()
            self.table_model.setTable("Clients")
            self.table_model.select()
            self.tableView.setModel(self.table_model)
            self.table_model.setHeaderData(0, QtCore.Qt.Horizontal, "Name")
            self.table_model.setHeaderData(1, QtCore.Qt.Horizontal, "Amount")
            self.table_model.setHeaderData(2, QtCore.Qt.Horizontal, "Date")
    
        def new_client(self):
            name = self.nameSlot.text()
            amount = self.amountSlot.text()
            date = self.toDay.text()
            record = self.table_model.record()
            record.setValue("Name", name)
            record.setValue("Amount", amount)
            record.setValue("Date", date)
            self.table_model.insertRecord(self.table_model.rowCount(), record)