Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Set selection background of disabled checkbox in pyqt5

I have a checkbox that is disabled (the user should not be able to toggle it) but I'm having trouble changing it's background when selected. I'm sure it has to do with the fact that box is disabled, but I'm not sure how to fix it. If there's an easy fix with stylesheets that would be ideal.

I tried messing around with slots/signals but that caused weird issues and I'd rather not fix this issue that way

from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWidgets import (QApplication,
          QTableView, QAbstractItemView)



class Ui_MainWindow(object):
   def setupUi(self, MainWindow):
       MainWindow.setObjectName("MainWindow")
       MainWindow.resize(400, 300)
       self.centralwidget = QtWidgets.QWidget(MainWindow)
       self.centralwidget.setObjectName("centralwidget")
       MainWindow.setCentralWidget(self.centralwidget)

       self.tableWidget = QtWidgets.QTableWidget(self.centralwidget)
       self.tableWidget.setGeometry(QtCore.QRect(50, 40, 310, 50))
       self.tableWidget.setSelectionBehavior(QAbstractItemView.SelectRows)
       self.tableWidget.setSelectionMode(QAbstractItemView. 
          SingleSelection)
       self.tableWidget.setEditTriggers(QAbstractItemView.NoEditTriggers)
       self.tableWidget.verticalHeader().setVisible(False)
       self.tableWidget.horizontalHeader().setVisible(False)
       self.tableWidget.setShowGrid(False)
       self.tableWidget.setStyleSheet("background-color: white; selection-background-color: #353535;")

       self.tableWidget.insertRow(0)

       self.tableWidget.insertColumn(0)
       self.tableWidget.insertColumn(1)
       self.tableWidget.insertColumn(2)


       self.tableWidget.checkBox = QtWidgets.QCheckBox(self.tableWidget)

       self.tableWidget.checkBox.setAttribute(QtCore.Qt.WA_TransparentForMouseEvents)
       self.tableWidget.checkBox.setFocusPolicy(QtCore.Qt.NoFocus)
       self.tableWidget.checkBox.setMaximumSize(30, 30)
       self.tableWidget.checkBox.setStyleSheet("background-color: white; selection-background-color: #353535; padding-left: 10px")
       self.tableWidget.checkBox.setChecked(True)


       self.tableWidget.setCellWidget(0, 1, self.tableWidget.checkBox)




if __name__ == "__main__":
   import sys
   app = QtWidgets.QApplication(sys.argv)
   MainWindow = QtWidgets.QMainWindow()
   ui = Ui_MainWindow()
   ui.setupUi(MainWindow)
   MainWindow.show()
   sys.exit(app.exec_())
like image 457
Sherief El-Ghazawi Avatar asked Jan 24 '26 22:01

Sherief El-Ghazawi


1 Answers

The problem in your case is that the QCheckBox to be selected must have the focus, but you have disabled it, and according to what you argue in your comments make me think that you have an XY problem: Your bottom problem is to have the selection per row and enable the checkbox status change depending on the data that the QTableWidget has.

Considering the above, it is not necessary to use a QCheckBox, just vast to enable the flag Qt::ItemIsUserCheckable, and use a delegate to enable or disable the change of state of the checkbox.

Considering the above, the solution is:

import random
from enum import Flag
from PyQt5 import QtCore, QtGui, QtWidgets


PermissionsRole = QtCore.Qt.UserRole + 1000


class Permissions(Flag):
    User = 0
    Admin = 1 << 0


class CheckBoxDelegate(QtWidgets.QStyledItemDelegate):
    def editorEvent(self, event, model, option, index):
        if index.data(PermissionsRole) & Permissions.Admin:
            super(CheckBoxDelegate, self).editorEvent(
                event, model, option, index
            )
        return False


class MainWindow(QtWidgets.QMainWindow):
    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)

        self.m_tablewidget = QtWidgets.QTableWidget(
            selectionBehavior=QtWidgets.QAbstractItemView.SelectRows,
            selectionMode=QtWidgets.QAbstractItemView.SingleSelection,
            editTriggers=QtWidgets.QAbstractItemView.NoEditTriggers,
            showGrid=False,
            columnCount=3,
        )
        delegate = CheckBoxDelegate(self.m_tablewidget)
        self.m_tablewidget.setItemDelegateForColumn(1, delegate)
        self.m_tablewidget.setStyleSheet(
            """
            QTableView
            {
                background-color: white; 
                selection-background-color: #353535;
            }
            """
        )
        for header in (
            self.m_tablewidget.horizontalHeader(),
            self.m_tablewidget.verticalHeader(),
        ):
            header.hide()
            if header.orientation() == QtCore.Qt.Horizontal:
                header.setSectionResizeMode(QtWidgets.QHeaderView.Stretch)

        for i in range(10):
            isAdmin = random.choice([Permissions.User, Permissions.Admin])
            self.m_tablewidget.insertRow(self.m_tablewidget.rowCount())
            self.m_tablewidget.setItem(
                i,
                0,
                QtWidgets.QTableWidgetItem(
                    "Is Admin?: {}".format(isAdmin == Permissions.Admin)
                ),
            )

            it = QtWidgets.QTableWidgetItem()
            it.setData(PermissionsRole, isAdmin)
            it.setFlags(it.flags() | QtCore.Qt.ItemIsUserCheckable)
            it.setCheckState(QtCore.Qt.Checked)
            self.m_tablewidget.setItem(i, 1, it)

        self.setCentralWidget(self.m_tablewidget)


if __name__ == "__main__":
    import sys

    app = QtWidgets.QApplication(sys.argv)
    w = MainWindow()
    w.resize(640, 480)
    w.show()
    sys.exit(app.exec_())
like image 166
eyllanesc Avatar answered Jan 27 '26 12:01

eyllanesc



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!