To this question I am referring to the answer from @Andy PyQt Tree Widget, adding check boxes for dynamic removal
There @Andy shows how to add CheckBox
into the QTreeWidget
, which works perfect.
I would like ask here, how to add RadioButton
into QTreeWidget
? ----And, which is more difficult for me, how to make only one item selectable, although they are in different groups
?
I rewrite the code from @Andy into PyQt5:
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *
import sys
def main():
app = QApplication (sys.argv)
tree = QTreeWidget ()
headerItem = QTreeWidgetItem()
item = QTreeWidgetItem()
for i in range(3):
parent = QTreeWidgetItem(tree)
parent.setText(0, "Parent {}".format(i))
parent.setFlags(parent.flags() | Qt.ItemIsTristate | Qt.ItemIsUserCheckable)
for x in range(5):
child = QTreeWidgetItem(parent)
child.setFlags(child.flags() | Qt.ItemIsUserCheckable)
child.setText(0, "Child {}".format(x))
child.setCheckState(0, Qt.Unchecked)
tree.show()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
The running result of the code above:
UPDATE: The desired result should be like as followings...
Any help will be highly appreciated! Thanks!
If you want to establish a QRadioButton
and it is exclusive in a group, a possible solution is to implement a delegate, in this delegate we will overwrite the paint
method to draw the QRadioButton
and the editorEvent
method to catch the click event and change the status of the other items according to be the case.
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *
import sys
class Delegate(QStyledItemDelegate):
def paint(self, painter, option, index):
if not index.parent().isValid():
QStyledItemDelegate.paint(self, painter, option, index)
else:
widget = option.widget
style = widget.style() if widget else QApplication.style()
opt = QStyleOptionButton()
opt.rect = option.rect
opt.text = index.data()
opt.state |= QStyle.State_On if index.data(Qt.CheckStateRole) else QStyle.State_Off
style.drawControl(QStyle.CE_RadioButton, opt, painter, widget)
def editorEvent(self, event, model, option, index):
value = QStyledItemDelegate.editorEvent(self, event, model, option, index)
if value:
if event.type() == QEvent.MouseButtonRelease:
if index.data(Qt.CheckStateRole) == Qt.Checked:
parent = index.parent()
for i in range(model.rowCount(parent)):
if i != index.row():
ix = parent.child(i, 0)
model.setData(ix, Qt.Unchecked, Qt.CheckStateRole)
return value
def main():
app = QApplication(sys.argv)
tree = QTreeWidget()
tree.setItemDelegate(Delegate())
for i in range(3):
parent = QTreeWidgetItem(tree)
parent.setText(0, "Parent {}".format(i))
for x in range(5):
child = QTreeWidgetItem(parent)
child.setFlags(child.flags() | Qt.ItemIsUserCheckable)
child.setText(0, "Child {}".format(x))
child.setCheckState(0, Qt.Unchecked)
tree.expandAll()
tree.show()
sys.exit(app.exec_())
if __name__ == '__main__':
main()