J'utilise la case à cocher QTableView Drapeau de Qt :: ItemiSuerCheckable em> Pour afficher une case à cocher dans une cellule de table. Après avoir lu certaines choses sur l'alignement dans une tentative de Cochez la case dans la cellule, Je retourne le qt :: aligncenter em> comme textalignmentrole de la fonction de données de modèles (). p> Ceci n'est cependant pas alignant ma case à cocher. P> Est-ce que quelqu'un sait comment utiliser les cases à cocher est ce mode? P> P>
7 Réponses :
Probablement pas la réponse que vous recherchez, mais j'ai trouvé qu'il est beaucoup plus facile de mettre en œuvre ma propre case à cocher l'article délégué lors de l'utilisation de QTableViews. P>
textalignmentrole signifie vraiment ce qu'il dit. Malheureusement, comme vous avez probablement remarqué, il ne semble pas y avoir de rôle d'alignement d'icône / widget disponible du tout. P>
rapport de bogue: http://bugreports.qt-project.org/browse/qtbug -9047 p>
Même question avec quelques réponses: http: //lists.trolltech. COM / QT-Intérêt / 2006-06 / msg00476.html P>
Après une enquête plus approfondie sur les options de délégué, j'ai trouvé une belle référence (malheureusement non disponible) et a trouvé l'hybride suivant à l'aide d'un QItemDelegate et isuserCable.
Essentiellement, vous devez prolonger qitemdelegate et répliquer, en utilisant le DrawCheck fonctionne em> fonctionner pour centrer et utiliser l'édition code> pour gérer les événements de la souris et du clavier lors de la réglage du modèle avec l'état approprié. P>
bool editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index)
2 des liens sont cassés
Aussi, vous pouvez regarder ce fil: http://www.qtcentre.org / threads / 19157-QTableView-Cochez la case-Centre-avec-stylesheet? p = 181413 # Post181413 P>
solution pour python (pyside, pyqt) pour centrer la case à cocher et avec modifiable autorisé: dans votre modèle de table, assurez-vous que les indicateurs permettent à l'utilisateur de vérifier / décocher la cellule. . p> Enfin, définissez le booleantelagate code> dans votre table p>
C'est la solution que j'ai proposée. Cela suppose que vous souhaitez que la case à cocher soit la seule chose dans la cellule.
class CenteredCheckboxDelegate final : public QStyledItemDelegate
{
public:
using QStyledItemDelegate::QStyledItemDelegate;
void paint(QPainter * painter, const QStyleOptionViewItem & o, const QModelIndex & index ) const override
{
auto option2 = o;
initStyleOption(&option2, index);
auto * widget = option2.widget;
auto * style = widget ? widget->style() : QApplication::style();
// Turn off all features and just draw the background
option2.state.setFlag(QStyle::State_HasFocus, false);
option2.features.setFlag(QStyleOptionViewItem::HasDisplay, false);
option2.features.setFlag(QStyleOptionViewItem::HasDecoration, false);
option2.features.setFlag(QStyleOptionViewItem::HasCheckIndicator, false);
style->drawControl(QStyle::CE_ItemViewItem, &option2, painter, widget);
// Then just draw the a checkbox centred in the cell
option2.rect = getCheckboxRect(option2);
auto stateFlag = option2.checkState == Qt::Checked ? QStyle::State_On : QStyle::State_Off;
option2.state.setFlag(stateFlag, true);
style->drawPrimitive(QStyle::PE_IndicatorViewItemCheck, &option2, painter, widget);
}
bool editorEvent(QEvent * event, QAbstractItemModel * model, const QStyleOptionViewItem & option, const QModelIndex & index) override
{
auto flags = index.flags();
if (!flags.testFlag(Qt::ItemIsUserCheckable) || !flags.testFlag(Qt::ItemIsEnabled))
{
return false;
}
if(event->type() == QEvent::MouseButtonRelease)
{
auto * mouseEvent = static_cast<QMouseEvent*>(event);
bool mouseOverCheckbox = getCheckboxRect(option).contains(mouseEvent->pos());
if(!mouseOverCheckbox) return false;
}
else if(event->type() == QEvent::KeyPress)
{
auto * keyEvent = static_cast<QKeyEvent*>(event);
if(keyEvent->key() != Qt::Key_Space) return false;
}
else
{
return false;
}
auto checkState = index.data(Qt::CheckStateRole).value<Qt::CheckState>();
auto toggledCheckState = checkState == Qt::Checked ? Qt::Unchecked : Qt::Checked;
return model->setData(index, toggledCheckState, Qt::CheckStateRole);
}
private:
QRect getCheckboxRect(const QStyleOptionViewItem & option) const
{
auto * widget = option.widget;
auto * style = widget ? widget->style() : QApplication::style();
auto checkboxSize = style->subElementRect(QStyle::SE_CheckBoxIndicator, &option, widget).size();
return QStyle::alignedRect(option.direction, Qt::AlignCenter, checkboxSize, option.rect);
}
};
Version PYQT5 / PYSIDE2, basée sur la version étonnante C ++ de Parker COATES
class QTableviewEditableDelegate(QStyledItemDelegate):
def __init__(self, alignment: Qt.Alignment, parent: Optional[QWidget] = None):
super().__init__(parent)
self.alignment: Qt.Alignment = alignment
self.parent = parent
if self.parent:
self.style = self.parent.style()
else:
self.style = QApplication.style()
def editorEvent(self, event: QMouseEvent, model: QAbstractItemModel, option: QStyleOptionViewItem,
index: QModelIndex) -> bool:
checkbox_data = index.data(Qt.CheckStateRole)
flags = index.flags()
if not (flags & Qt.ItemIsUserCheckable) or not (flags & Qt.ItemIsEnabled) or checkbox_data is None:
return False
else:
if event.type() == QEvent.MouseButtonRelease:
mouseover_checkbox: bool = self.get_checkbox_rect(option).contains(event.pos())
if not mouseover_checkbox:
return False
elif event.type() == QEvent.KeyPress and event.key() != Qt.Key_Space:
return False
else:
return False
if checkbox_data == Qt.Checked:
checkbox_toggled: int = Qt.Unchecked
else:
checkbox_toggled: int = Qt.Checked
return model.setData(index, checkbox_toggled, Qt.CheckStateRole)
def get_checkbox_rect(self, option: QStyleOptionViewItem) -> QRect:
widget = option.widget
if widget:
style = widget.style()
else:
style = self.style()
checkbox_size: QSize = style.subElementRect(QStyle.SE_CheckBoxIndicator, option, widget).size()
return QStyle.alignedRect(option.direction, Qt.AlignCenter, checkbox_size, option.rect)
def paint(self, painter: QPainter, option: QStyleOptionViewItem, index: QModelIndex):
try:
self.initStyleOption(option, index)
painter.save()
flags: Qt.ItemFlags = index.model().flags(index)
widget: Optional[QWidget] = option.widget
checkbox_data = index.data(Qt.CheckStateRole)
if widget:
style = widget.style()
else:
style = self.style()
if option.HasCheckIndicator and checkbox_data is not None:
option_checkbox = option
self.initStyleOption(option_checkbox, index)
option_checkbox.state = option_checkbox.state & ~QStyle.State_HasFocus
option_checkbox.features = option_checkbox.features & ~QStyleOptionViewItem.HasDisplay
option_checkbox.features = option_checkbox.features & ~QStyleOptionViewItem.HasDecoration
option_checkbox.features = option_checkbox.features & ~QStyleOptionViewItem.HasCheckIndicator
style.drawControl(QStyle.CE_ItemViewItem, option_checkbox, painter, widget)
# Then just draw the a checkbox centred in the cell
option_checkbox.rect = self.get_checkbox_rect(option_checkbox)
if option_checkbox.checkState == Qt.Checked:
state_flag = QStyle.State_On
else:
state_flag = QStyle.State_Off
option_checkbox.state = option_checkbox.state | state_flag
style.drawPrimitive(QStyle.PE_IndicatorViewItemCheck, option_checkbox, painter, widget)
else:
QStyledItemDelegate.paint(self, painter, option, index)
painter.restore()
except Exception as e:
print(repr(e))