18

これが私がやろうとしていることです(すべての親と子は右側に閉じるボタンが必要です。将来的には、ホバーされたアイテムのみが**閉じる**ボタンを表示できるようになります):

ここに画像の説明を入力

私のデリゲートコード:

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接続コード付き:

recipientsView()->setItemDelegateForColumn( 1, new CloseButton( this ) );

recipientsView()単純なですQTreeWidget

問題は、QToolButtonがまったく表示されないことです (2 番目の列にある必要があります。つまり、ツリーの列インデックスは です1)。私が間違っていることは何ですか?

デリゲートに関するすべての Qt デモの例と、QItemDelegateおよび同様のものに関する最初の Google の結果を既に確認しました。

4

3 に答える 3

22

関数を使用QStyledDelegate::paintして、ウィジェットを使用せずに閉じるアイコンを描画しeditorEventたり、エディターを使用しない場合やアイテムを編集可能にした場合でも、アイテムのマウス イベントを受け取ることができます。

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)
};
于 2011-08-24T15:23:22.420 に答える
1

まず、QTreeWidgetを実際に使用しているのか、それともQTreeViewを使用しているのかを尋ねる必要があります。QTreeViewのドキュメントによると、QTreeWidgetでカスタムデリゲートを使用することはできません。カスタムデリゲートを使用できるようにするには、QTree *View*と何らかの形式のQAbstractItemModelを使用する必要があります。

ああ、それをスクラッチします。QTreeView関数であるsetItemDelegateForColumnを呼び出しているようですが、違いに注意する必要があるため、上記の段落を保持しています。:)

モデルのflags()関数がアイテムフラグの一部としてQt::ItemIsEditableを返していることを確認します。createEditor()メソッドは、編集イベントがビューによって報告されるたびに呼び出されます。(編集をトリガーするビューイベントは、モデルのEditTriggersによって異なります)通常、デリゲートをダブルクリックすると、特にデフォルトで編集がトリガーされます。

ただし、閉じるボタンをダブルクリックでのみ表示したいのではないかと思います。ボタンを常に表示するには、デリゲートのpaint()関数を再実装して、ボタンを描画する必要があります。QtのStarDelegateの例は、この点で非常に役立つことがわかりました。また、それも役立つと思います。

于 2011-08-24T13:52:26.217 に答える
-1

このように QTreeWidget で QItemDelegate を使用できます (PyQt の例、申し訳ありません)。

myTreeWidget = QtGui.QTreeWidget()
myTreeWidget.setItemDelegate(myDelegate())

class myDelegate(QtGui.QItemDelegate):
    def paint(self, painter, option, index):

        #Custom Draw Column 1
        if index.column() == 1:
            icon = QtGui.QIcon(index.data(QtCore.Qt.DecorationRole))
            if icon:
                icon.paint(painter, option.rect)
                #You'll probably want to pass a different QRect

        #Use the standard routine for other columns
        else:
            super(myDelegate, self).paint(painter, option, index)
于 2011-09-06T16:32:10.757 に答える