如何为 QTreeWidget 创建委托?
这是我正在尝试做的(所有父母和孩子都必须在右侧有一个关闭按钮,将来,只有悬停的项目才能显示**关闭** 按钮):
Here is what I'm trying to do (all parents and children must have a close button on the right, in the future, only the hovered item will be able to show the **close ** button):
我的委托代码:
class CloseButton : public QItemDelegate
{
Q_OBJECT
public:
CloseButton( QObject* parent = 0 )
: QItemDelegate( parent )
{};
QWidget* createEditor( QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index ) const
{
if ( index.column() == 1 )
{
QToolButton* button = new QToolButton( parent );
button->setIcon( QIcon( CLOSE_ICON ) );
//button->setFixedSize( 16, 16 );
//button->setAutoRaise( true );
//button->setVisible( true );
CONNECT( button, SIGNAL( clicked() ), this, SLOT( emitCommitData() ) );
return button;
}
return ( new QWidget );
}
private slots:
void emitCommitData()
{
emit commitData( qobject_cast< QWidget* >( sender() ) );
}
private:
//Q_DISABLE_COPY( CloseButton );
};
与QTreeWidget
连接代码:
With QTreeWidget
connection code:
recipientsView()->setItemDelegateForColumn( 1, new CloseButton( this ) );
其中 recipientsView()
是一个简单的 QTreeWidget
.
where recipientsView()
is a simple QTreeWidget
.
问题是 QToolButton
根本没有显示(它必须在第二列,即树中的列索引是 1
).我做错了什么?
Problem is that QToolButton
s are not shown at all (it must be in the second column, i.e. column index in the tree is 1
). What I'm doing wrong?
我已经检查了所有关于委托的 Qt 演示示例以及关于 QItemDelegate
和类似内容的第一个 Google 结果.
I have checked already all Qt demo examples about delegates and the first Google result about QItemDelegate
's and similar stuff.
推荐答案
您可以使用 QStyledDelegate::paint
函数来绘制关闭图标,而无需使用任何小部件,以及 editorEvent
接收项目的鼠标事件,即使您不使用编辑器或使项目可编辑.
You can use the QStyledDelegate::paint
function to draw the close icon, without using any widget, and the editorEvent
to receive mouse events for the item, even if you don't use the editor or make the item editable.
class CloseButton : public QStyledItemDelegate {
Q_OBJECT
public:
explicit CloseButton(QObject *parent = 0,
const QPixmap &closeIcon = QPixmap())
: QStyledItemDelegate(parent)
, m_closeIcon(closeIcon)
{
if(m_closeIcon.isNull())
{
m_closeIcon = qApp->style()
->standardPixmap(QStyle::SP_DialogCloseButton);
}
}
QPoint closeIconPos(const QStyleOptionViewItem &option) const {
return QPoint(option.rect.right() - m_closeIcon.width() - margin,
option.rect.center().y() - m_closeIcon.height()/2);
}
void paint(QPainter *painter, const QStyleOptionViewItem &option,
const QModelIndex &index) const {
QStyledItemDelegate::paint(painter, option, index);
// Only display the close icon for top level items...
if(!index.parent().isValid()
// ...and when the mouse is hovering the item
// (mouseTracking must be enabled on the view)
&& (option.state & QStyle::State_MouseOver))
{
painter->drawPixmap(closeIconPos(option), m_closeIcon);
}
}
QSize sizeHint(const QStyleOptionViewItem &option,
const QModelIndex &index) const
{
QSize size = QStyledItemDelegate::sizeHint(option, index);
// Make some room for the close icon
if(!index.parent().isValid()) {
size.rwidth() += m_closeIcon.width() + margin * 2;
size.setHeight(qMax(size.height(),
m_closeIcon.height() + margin * 2));
}
return size;
}
bool editorEvent(QEvent *event, QAbstractItemModel *model,
const QStyleOptionViewItem &option,
const QModelIndex &index)
{
// Emit a signal when the icon is clicked
if(!index.parent().isValid() &&
event->type() == QEvent::MouseButtonRelease) {
QMouseEvent *mouseEvent = static_cast<QMouseEvent*>(event);
QRect closeButtonRect = m_closeIcon.rect()
.translated(closeIconPos(option));
if(closeButtonRect.contains(mouseEvent->pos()))
{
emit closeIndexClicked(index);
}
}
return false;
}
signals:
void closeIndexClicked(const QModelIndex &);
private:
QPixmap m_closeIcon;
static const int margin = 2; // pixels to keep arount the icon
Q_DISABLE_COPY(CloseButton)
};
相关文章