Home > Software design >  Change button function at runtime in pyqt5
Change button function at runtime in pyqt5

Time:07-19

When the program starts running, I assign the CreateNew function to the btn_UpdateDelete button in the constructor function. But I want to replace it with UpdateFunc after the program starts running. When I click the Update button after the program starts running, the CreateNew function works. Is there a method to clear the functions I assigned earlier?

from PyQt5 import QtWidgets
from PyQt5.QtWidgets import QTableWidgetItem
from gui4 import Ui_mainWindow
import sys
from Database import Database
class Window(QtWidgets.QMainWindow):
    def __init__(self):
        super(Window, self).__init__()
        self.ui = Ui_mainWindow()
        self.ui.setupUi(self)
        self.LoadData()
        self.ui.btn_UpdateAdd.clicked.connect(self.CreateNew)
        self.ui.btn_Delete.clicked.connect(self.Delete)
        self.ui.tableWidget.clicked.connect(self.doubleClick)
        self.ui.btn_Reset.clicked.connect(self.Reset)
        self.selectedId = -1
        self.selectedRowId = -1

    def LoadData(self):
        data = Database.getInstance().BringAllTheData()
        self.ui.tableWidget.setRowCount(len(data))
        self.ui.tableWidget.setColumnCount(5)
        count = 0
        for d in data:
            self.ui.tableWidget.setItem(count, 0, QtWidgets.QTableWidgetItem(str(d[0])))
            self.ui.tableWidget.setItem(count, 1, QtWidgets.QTableWidgetItem(d[1]))
            self.ui.tableWidget.setItem(count, 2, QtWidgets.QTableWidgetItem(str(d[2])))
            self.ui.tableWidget.setItem(count, 3, QtWidgets.QTableWidgetItem(str(d[3])))
            self.ui.tableWidget.setItem(count, 4, QtWidgets.QTableWidgetItem(str(d[4])))
            count = count   1

    def CreateNew(self):
        database = Database.getInstance()
        lectureName = self.ui.lineEdit.text()
        noteOne = self.ui.lineEdit_2.text()
        noteTwo = self.ui.lineEdit_3.text()
        noteThree = self.ui.lineEdit_4.text()
        if lectureName is not None and noteOne is not None and noteTwo is not None and noteThree is not None:
            database.Create(lectureName, int(noteOne), int(noteTwo), int(noteThree))
        self.Reset()
        self.LoadData()

    def clearLines(self):
        self.ui.lineEdit.clear()
        self.ui.lineEdit_2.clear()
        self.ui.lineEdit_3.clear()
        self.ui.lineEdit_4.clear()

    def Reset(self):
        self.selectedId = -1
        self.selectedRowId = -1
        self.clearLines()
        self.ui.btn_UpdateAdd.setText('Add')
        self.ui.btn_UpdateAdd.clicked.connect(self.CreateNew)

    def doubleClick(self):
        database = Database.getInstance()
        for item in self.ui.tableWidget.selectedItems():
            print(item.row(), item.column(), item.text())
            if item.column() == 0:
                self.selectedId = int(item.text())
            else:
                self.selectedId = -1
            self.selectedRowId = self.ui.tableWidget.item(item.row(), 0).text()
        data = database.BringById(int(self.selectedRowId))
        self.ui.lineEdit.setText(str(data[0][1]))
        self.ui.lineEdit_2.setText(str(data[0][2]))
        self.ui.lineEdit_3.setText(str(data[0][3]))
        self.ui.lineEdit_4.setText(str(data[0][4]))
        self.ui.btn_UpdateAdd.setText('Update')
        self.ui.btn_UpdateAdd.clicked.connect(self.UpdateFunc)
        print(self.selectedId)
        print(self.selectedRowId)

    def Delete(self):
        database = Database.getInstance()
        if self.selectedId != -1:
            print(self.selectedId)
            database.DeleteById(int(self.selectedId))
            self.LoadData()
            self.clearLines()

    def UpdateFunc(self):
        database = Database.getInstance()
        lectureName = self.ui.lineEdit.text()
        noteOne = self.ui.lineEdit_2.text()
        noteTwo = self.ui.lineEdit_3.text()
        noteThree = self.ui.lineEdit_4.text()
        if lectureName is not None and noteOne is not None and noteTwo is not None and noteThree is not None:
            database.Update(self.selectedRowId, lectureName, int(noteOne), int(noteTwo), int(noteThree))
        self.clearLines()
        self.LoadData()
def create_app():
app = QtWidgets.QApplication(sys.argv)
win = Window()
win.show()
sys.exit(app.exec_())
create_app()

CodePudding user response:

Just like there is the connect method to assign signals to slots, there is a disconnect method that removes previously connected slots. So in your CreateNew method at the bottom you can disconnect the method from your signal and attach the UpdateFunc method as the new slot.

    def CreateNew(self):
        database = Database.getInstance()
        lectureName = self.ui.lineEdit.text()
        noteOne = self.ui.lineEdit_2.text()
        noteTwo = self.ui.lineEdit_3.text()
        noteThree = self.ui.lineEdit_4.text()
        if lectureName is not None and noteOne is not None and noteTwo is not None and noteThree is not None:
            database.Create(lectureName, int(noteOne), int(noteTwo), int(noteThree))
        self.Reset()
        self.LoadData()
        self.ui.btn_UpdateAdd.clicked.disconnect(self.CreateNew)
        self.ui.btn_UpdateAdd.clicked.connect(self.UpdateFunc)

Alternatively, you could simply set a flag attribute on your class instance DatabaseCreated and set it to False, and update it upon the creation of the database. This would avoid having to need to seperate functions that nearly identical.

For example:

class Window(QtWidgets.QMainWindow):
    def __init__(self):
        super(Window, self).__init__()
        ...
        self.ui.btn_UpdateAdd.clicked.connect(self.updateFunc)
        self.dbCreated = False
        ...

    def updateFunc(self):
        database = Database.getInstance()
        lectureName = self.ui.lineEdit.text()
        noteOne = self.ui.lineEdit_2.text()
        noteTwo = self.ui.lineEdit_3.text()
        noteThree = self.ui.lineEdit_4.text()
        if lectureName is not None and noteOne is not None and noteTwo is not None and noteThree is not None:
            if not self.dbCreated:
                database.Create(lectureName, int(noteOne), int(noteTwo), int(noteThree))
                self.dbCreated = True
            else:
                database.Update(self.selectedRowId, lectureName, int(noteOne), int(noteTwo), int(noteThree))
        self.Reset()
        self.LoadData()

This way you can complete get rid of the StartNew method, and don't need to worry about disconnecting the signal.

  • Related