我试图使QStyledItemDelegate的行为类似于我编写的自定义QWidget,因此我可以将代码切换为模型/视图方法。
自定义QWidget是一个复杂的按钮,它在鼠标悬停的角落显示四个“子按钮”(所以总共有五个信号)。它还可以使用自定义拖动像素图进行拖放操作。为此,我使用了mousePressEvent,mouseReleaseEvent,mouseMoveEvent,enterEvent和leaveEvent。这是鼠标悬停时显示的“子按钮”的样子:
我已经将我的主代码切换为使用模型/视图方法,并尝试将此小部件用作我的自定义ListView的QStyledItemDelegate。 我已经尝试将自定义Widget指定为这样的编辑器:
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
这看起来很有希望,因为它为我点击的项目绘制了“FancyButton”类。但是,我需要这是一个鼠标悬停事件。 经过一番研究后,我尝试将QAbstractItemView.entered插槽连接到QAbstractItemView.edit信号:
self.entered.connect( self.edit )
这仅适用于我将鼠标指针移过的第一项,然后我收到这些错误:
edit: editing failed
所以现在我又遇到了这些问题:
我有一种感觉,我正朝着错误的方向前进。
答案 0 :(得分:1)
我敦促你回到代表而不是小部件,纯粹出于性能原因=)
您可以使用状态,特别是QStyle :: State_MouseOver,使用委托鼠标覆盖paint方法中的事件。对于按钮上的点击,您可以覆盖接收所有鼠标事件的editorEvent,然后处理发生鼠标点击的区域。例如:
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;
}
此外,您可以查看此主题HowTo create delegate for QTreeWidget?,这适用于QTreeWidget,但我认为同样的方法也适用于您的情况。
答案 1 :(得分:0)
AFAIK,您不能使用自定义小部件来查看List / Table / Tree-View-delegates中的项目。您可以使用它们进行编辑,但如果视图模式除了重绘之外还需要其他任何内容,那么您会非常难过。
我们通过拥有自己的容器小部件来解决这个问题,这些小部件可以监听模型事件并动态添加/删除项目小部件。真的很遗憾,因为它感觉很基本。
原因可能是视图应该很快且能够显示很多项目,并且拥有大量小部件并不快,所以他们选择只允许自定义重绘功能(允许他们使用justone容器小部件,在不同区域使用自定义绘画。)
也许有办法绕过它,如果有的话,我会很高兴听到它。
<强>更新强>
如果您需要捕获事件,也许您可以在容器视图中安装事件过滤器,然后使用QListView::indexAt找到要将事件发送到的正确项目/窗口小部件/委托?
然后您可以在mouseenter / leave上使用openPersistentEditor和closePersistentEditor来启用编辑,即显示/关闭项目上的自定义小部件。