在pyqt5中设置禁用复选框的选择背景
Set selection background of disabled checkbox in pyqt5
我有一个复选框被禁用(用户不应该能够切换它)但是我在选择它时无法更改它的背景。我确定这与盒子被禁用的事实有关,但我不确定如何修复它。如果有一个简单的样式表修复,那将是理想的。
我试着弄乱 slots/signals 但这导致了奇怪的问题,我不想那样解决这个问题
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_())
你的问题是要选择的 QCheckBox 必须有焦点,但你禁用了它,根据你在评论中的争论,我认为你有一个 XY problem:您的根本问题是让每行选择并根据 QTableWidget 拥有的数据启用复选框状态更改。
考虑到以上情况,没有必要使用 QCheckBox,只需大量启用标志 Qt::ItemIsUserCheckable,并使用委托来启用或禁用复选框的状态更改。
综合以上,解决方案是:
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_())
我有一个复选框被禁用(用户不应该能够切换它)但是我在选择它时无法更改它的背景。我确定这与盒子被禁用的事实有关,但我不确定如何修复它。如果有一个简单的样式表修复,那将是理想的。
我试着弄乱 slots/signals 但这导致了奇怪的问题,我不想那样解决这个问题
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_())
你的问题是要选择的 QCheckBox 必须有焦点,但你禁用了它,根据你在评论中的争论,我认为你有一个 XY problem:您的根本问题是让每行选择并根据 QTableWidget 拥有的数据启用复选框状态更改。
考虑到以上情况,没有必要使用 QCheckBox,只需大量启用标志 Qt::ItemIsUserCheckable,并使用委托来启用或禁用复选框的状态更改。
综合以上,解决方案是:
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_())