3

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_())
eyllanesc
  • 235,170
  • 19
  • 170
  • 241
  • I do not understand you, explain yourself better – eyllanesc Jun 28 '19 at 22:04
  • If you run the current code and select the row, you’ll see that then entire row changes the background color to gray, but the area around the checkbox does not change background color, it remains white. I want to modify it so that when the row is selected, the entire checkbox background area becomes gray. – Sherief El-Ghazawi Jun 29 '19 at 03:47
  • Why do you disable the focus of the QCheckBox? – eyllanesc Jun 29 '19 at 04:00
  • Because I don’t want the user to be able to do anything with it. In the actual project the checkbox is checked based on user privileges – Sherief El-Ghazawi Jun 29 '19 at 17:09

1 Answers1

3

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_())
eyllanesc
  • 235,170
  • 19
  • 170
  • 241