Vidya Marathe
Vidya Marathe

Reputation: 443

Enable/Disable QPushButton upon row selection in QTableWidget

I have a QTableWidget and a Delete QPushButton.

I want the delete button to be enabled only when a row is selected from QTableWidget and if no row is selected then button should be disabled.

While initialization I am doing:

#Make rows selectable
self.tableWidget.setSelectionBehavior(QtWidgets.QTableWidget.SelectRows)
# Diable button initially
if not len(self.tableWidget.selectionModel().selectedRows()):
        self.btnDelete.setEnabled(False)

This sets Delete button to the disabled state.

How to I enable it on row selection?

Using: Python 3.8 , PyQt5 on Windows10

EDIT 1: Minimum working example:

import sys
from PyQt5 import QtWidgets
from PyQt5.QtWidgets import QApplication, QWidget, QTableWidget, QTableWidgetItem, QVBoxLayout
from PyQt5.QtCore import pyqtSlot

class App(QWidget):

    def __init__(self):
        super().__init__()
        self.title = 'Fruits'
        self.left = 0
        self.top = 0
        self.width = 300
        self.height = 200
        self.initUI()

    def initUI(self):
        self.setWindowTitle(self.title)
        self.setGeometry(self.left, self.top, self.width, self.height)
        self.createTable()

        self.btndelete = QtWidgets.QPushButton("DELETE")
        self.btndelete.setObjectName("btndelete")
        self.btndelete.clicked.connect(self.deleteRow)
        if not len(self.tableWidget.selectionModel().selectedRows()):
            self.btndelete.setEnabled(False)

        self.layout = QVBoxLayout()
        self.layout.addWidget(self.tableWidget) 
        self.layout.addWidget(self.btndelete)

        self.setLayout(self.layout) 

        # Show widget
        self.show()

    def createTable(self):
       # Create table
        self.tableWidget = QTableWidget()
        self.tableWidget.setRowCount(4)
        self.tableWidget.setColumnCount(2)
        self.tableWidget.setItem(0,0, QTableWidgetItem("Apple"))
        self.tableWidget.setItem(0,1, QTableWidgetItem("15"))
        self.tableWidget.setItem(1,0, QTableWidgetItem("Banana"))
        self.tableWidget.setItem(1,1, QTableWidgetItem("11"))
        self.tableWidget.setItem(2,0, QTableWidgetItem("Dogs"))
        self.tableWidget.setItem(2,1, QTableWidgetItem("10"))
        self.tableWidget.setItem(3,0, QTableWidgetItem("Cats"))
        self.tableWidget.setItem(3,1, QTableWidgetItem("2"))
        self.tableWidget.move(0,0)

        # table selection 
        self.tableWidget.setSelectionBehavior(QtWidgets.QTableWidget.SelectRows)

    def deleteRow(self):
        pass

    @pyqtSlot()
    def on_click(self):
        print("\n")
        for currentQTableWidgetItem in self.tableWidget.selectedItems():
            print(currentQTableWidgetItem.row(), currentQTableWidgetItem.column(), currentQTableWidgetItem.text())


if __name__ == '__main__':
    app = QApplication(sys.argv)
    ex = App()
    sys.exit(app.exec_()) 

Upvotes: 1

Views: 1371

Answers (2)

eyllanesc
eyllanesc

Reputation: 244301

You have to use the selectionChanged signal of the selectionModel associated to the QTableWidget to change the state of the button based on the number of rows selected:

    # ...
    self.tableWidget.setSelectionBehavior(QtWidgets.QTableWidget.SelectRows)
    self.tableWidget.selectionModel().selectionChanged.connect(
        self.on_selection_changed
    )
    self.on_selection_changed()

def on_selection_changed(self):
    self.btnDelete.setEnabled(
        bool(self.tableWidget.selectionModel().selectedRows())
    )

MWE:

import sys
from PyQt5.QtWidgets import (
    QApplication,
    QWidget,
    QTableWidget,
    QTableWidgetItem,
    QPushButton,
    QVBoxLayout,
)
from PyQt5.QtCore import pyqtSlot


class App(QWidget):
    def __init__(self):
        super().__init__()
        self.title = "Fruits"
        self.left = 0
        self.top = 0
        self.width = 300
        self.height = 200
        self.initUI()

    def initUI(self):
        self.setWindowTitle(self.title)
        self.setGeometry(self.left, self.top, self.width, self.height)
        self.createTable()

        self.btndelete = QPushButton("DELETE")
        self.btndelete.setObjectName("btndelete")
        self.btndelete.clicked.connect(self.deleteRow)

        self.on_selection_changed()

        lay = QVBoxLayout(self)
        lay.addWidget(self.tableWidget)
        lay.addWidget(self.btndelete)

        # Show widget
        self.show()

    def createTable(self):
        # Create table
        self.tableWidget = QTableWidget(4, 2)
        self.tableWidget.setItem(0, 0, QTableWidgetItem("Apple"))
        self.tableWidget.setItem(0, 1, QTableWidgetItem("15"))
        self.tableWidget.setItem(1, 0, QTableWidgetItem("Banana"))
        self.tableWidget.setItem(1, 1, QTableWidgetItem("11"))
        self.tableWidget.setItem(2, 0, QTableWidgetItem("Dogs"))
        self.tableWidget.setItem(2, 1, QTableWidgetItem("10"))
        self.tableWidget.setItem(3, 0, QTableWidgetItem("Cats"))
        self.tableWidget.setItem(3, 1, QTableWidgetItem("2"))

        # table selection
        self.tableWidget.setSelectionBehavior(QTableWidget.SelectRows)
        self.tableWidget.selectionModel().selectionChanged.connect(
            self.on_selection_changed
        )

    @pyqtSlot()
    def on_selection_changed(self):
        self.btndelete.setEnabled(
            bool(self.tableWidget.selectionModel().selectedRows())
        )

    def deleteRow(self):
        pass


if __name__ == "__main__":
    app = QApplication(sys.argv)
    ex = App()
    sys.exit(app.exec_())

Upvotes: 2

shaik moeed
shaik moeed

Reputation: 5785

Try this, to enable a button.

self.btnDelete.setDisabled(False)

Or

you can try

bool_enable = len(self.tableWidget.selectionModel().selectedRows()) > 0
self.btnDelete.setEnabled(bool_enable)

Upvotes: 0

Related Questions