Last active
December 15, 2020 11:05
-
-
Save eyllanesc/ade64a8cd1bd534d473b51a3aec888c5 to your computer and use it in GitHub Desktop.
Translate from C++ to PySide2: https://wiki.qt.io/Technical_FAQ#How_can_I_align_the_checkboxes_in_a_view.3F
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from PySide2.QtCore import Qt, QSize, QRect, QEvent | |
from PySide2.QtWidgets import QStyledItemDelegate, QStyleOptionViewItem, QApplication, QStyle, QTableWidget, \ | |
QTableWidgetItem | |
class ItemDelegate(QStyledItemDelegate): | |
def paint(self, painter, option, index): | |
opt = QStyleOptionViewItem(option) | |
if index.column() == 0: | |
textMargin = QApplication.style().pixelMetric(QStyle.PM_FocusFrameHMargin) + 1 | |
newRect = QStyle.alignedRect(option.direction, Qt.AlignCenter, | |
QSize(option.decorationSize.width() + 5, | |
option.decorationSize.height()), | |
QRect(option.rect.x() + textMargin, option.rect.y(), | |
option.rect.width() - (2 * textMargin), | |
option.rect.height())) | |
opt.rect = newRect | |
QStyledItemDelegate.paint(self, painter, opt, index) | |
def editorEvent(self, event, model, option, index): | |
flags = model.flags(index) | |
if not (flags & Qt.ItemIsUserCheckable) or not (flags & Qt.ItemIsEnabled): | |
return False | |
value = index.data(Qt.CheckStateRole) | |
if event.type() == QEvent.MouseButtonRelease: | |
textMargin = QApplication.style().pixelMetric(QStyle.PM_FocusFrameHMargin) + 1 | |
checkRect = QStyle.alignedRect(option.direction, Qt.AlignCenter, | |
option.decorationSize, | |
QRect(option.rect.x() + (2 * textMargin), | |
option.rect.y(), | |
option.rect.width() - (2 * textMargin), | |
option.rect.height())) | |
if not checkRect.contains(event.pos()): | |
return False | |
elif event.type() == QEvent.KeyPress: | |
if event.key() != Qt.Key_Space and event.key() != Qt.Key_Select: | |
return False | |
else: | |
return False | |
state = Qt.Unchecked if value == Qt.Checked else Qt.Checked | |
return model.setData(index, state, Qt.CheckStateRole) | |
class Table(QTableWidget): | |
def __init__(self): | |
QTableWidget.__init__(self, 3, 1) | |
self.setItemDelegate(ItemDelegate(self)) | |
for i in range(self.rowCount()): | |
for j in range(self.columnCount()): | |
it = QTableWidgetItem() | |
self.setItem(i, j, it) | |
it.setFlags(Qt.ItemIsEnabled | Qt.ItemIsUserCheckable) | |
it.setCheckState(Qt.Checked if (i + j) % 2 == 0 else Qt.Unchecked) | |
if __name__ == '__main__': | |
import sys | |
app = QApplication(sys.argv) | |
w = Table() | |
w.show() | |
sys.exit(app.exec_()) |
@sharpordie try with this code:
from PySide2.QtCore import Qt
from PySide2.QtWidgets import (
QApplication,
QProxyStyle,
QStyle,
QTableWidget,
QTableWidgetItem,
)
class ProxyStyle(QProxyStyle):
def subElementRect(self, e, opt, widget):
r = super().subElementRect(e, opt, widget)
if e == QStyle.SE_ItemViewItemCheckIndicator:
r.moveCenter(opt.rect.center())
return r
class Table(QTableWidget):
def __init__(self):
QTableWidget.__init__(self, 3, 1)
self._style = ProxyStyle(self.style())
self.setStyle(self._style)
for i in range(self.rowCount()):
for j in range(self.columnCount()):
it = QTableWidgetItem()
self.setItem(i, j, it)
it.setFlags(Qt.ItemIsEnabled | Qt.ItemIsUserCheckable)
it.setCheckState(Qt.Checked if (i + j) % 2 == 0 else Qt.Unchecked)
if __name__ == "__main__":
import sys
app = QApplication(sys.argv)
w = Table()
w.show()
sys.exit(app.exec_())
Sorry for the HUGE delay.
Thank you very much, it's working perfectly.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Thanks for this code snippet.
Would you know how to remove the weird thing on the right side of the active cell?