I am trying to make a QStyledItemDelegate behave like a custom QWidget I wrote, so I can switch my code to a model/view approach.
The custom QWidget is a complex button which shows four "sub buttons" in it's corners on mouse over (so all in all there are five signals). It's also drag&droppable with a custom drag pixmap. To achieve this I am using mousePressEvent, mouseReleaseEvent, mouseMoveEvent, enterEvent and leaveEvent. This is what it looks like with and without the "sub buttons" shown on mouse over:
I have since switched my main code to use a model/view approach and am trying to use this widget as a QStyledItemDelegate for my customised ListView. I have tried assigning the custom Widget as an editor like this:
class ToolButtonDelegate( QStyledItemDelegate ):
def __init__( self, parent=None ):
super( ToolButtonDelegate, self).__init__( parent )
self.parent = parent
def createEditor( self, parent, option, index ):
if not index.isValid():
return False
btn = FancyButton( index.data( Qt.UserRole ), parent=parent )
return btn
This seems promising as it draws the "FancyButton" class for the item I click on. However, I need this to be a mouse over event. After a bit more research I tried connecting the QAbstractItemView.entered slot to QAbstractItemView.edit signal:
self.entered.connect( self.edit )
This works only for the first item I move my mouse pointer over, then I get these errors:
edit: editing failed
So now I'm stuck again with these problems:
I have a feeling I'm heading into the wrong direction here.
I'd urge you to go back to delegates instead of widgets, purely for performance reasons =)
You can work with delegates mouse over events in paint method using states, particularly QStyle::State_MouseOver. As for clicks on buttons you can override editorEvent which receives all mouse events and then work with regions of where mouse clicks occurred. For example:
void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
if (option.state & QStyle::State_MouseOver)
{
// draw stuff which appears on mouse over
} else {
// draw stuff that appears when mouse is not over control
}
}
bool editorEvent(QEvent *event, QAbstractItemModel*, const QStyleOptionViewItem &option, const QModelIndex &index)
{
// Emit a signal when the icon is clicked
if(event->type() == QEvent::MouseButtonRelease)
{
QMouseEvent *mouseEvent = static_cast<QMouseEvent*>(event);
QRect editButtonRect = editIcon.rect().translated(editIconPos(option));
QRect deleteButtonRect = deleteIcon.rect().translated(deleteIconPos(option));
if(editButtonRect.contains(mouseEvent->pos()))
{
emit editIndexClicked(index);
} else if (deleteButtonRect.contains(mouseEvent->pos())) {
emit deleteIndexClicked(index);
}
}
return false;
}
Also you can check out this topic HowTo create delegate for QTreeWidget?, this is for QTreeWidget, but I think same methods would apply to your case too.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With