3

QStyledItemDelegate を作成したカスタム QWidget のように動作させようとしているので、コードをモデル/ビュー アプローチに切り替えることができます。

カスタム QWidget は複雑なボタンで、マウス オーバー時に四隅に 4 つの「サブ ボタン」が表示されます (つまり、全部で 5 つのシグナルがあります)。カスタム ドラッグ ピックスマップを使用してドラッグ アンド ドロップすることもできます。これを実現するために、mousePressEvent、mouseReleaseEvent、mouseMoveEvent、enterEvent、および leaveEvent を使用しています。これは、マウスオーバーで表示される「サブボタン」がある場合とない場合の外観です。 ここに画像の説明を入力

それ以来、メイン コードをモデル/ビュー アプローチを使用するように切り替え、このウィジェットをカスタマイズした ListView の QStyledItemDelegate として使用しようとしています。次のようなエディターとしてカスタム ウィジェットを割り当ててみました。

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

だから今、私はこれらの問題で再び立ち往生しています:

  • エディターを適切に閉じる方法 (「QAbstractItemView.leave」イベントなどはありません)。
  • QAbstractIremView と対話するだけでなく、マウス クリックが実際に FanyButton クラスのボタンをトリガーするようにする方法

ここで間違った方向に進んでいるような気がします。

4

2 に答える 2

3

純粋にパフォーマンス上の理由から、ウィジェットではなくデリゲートに戻ることをお勧めします =)

ステート、特に QStyle::State_MouseOver を使用して、ペイント メソッドでデリゲートのマウス オーバー イベントを操作できます。ボタンのクリックに関しては、すべてのマウス イベントを受け取る 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;
    }

また、このトピックQTreeWidgetのデリゲートを作成する方法を確認できますか? 、これは QTreeWidget 用ですが、同じ方法があなたのケースにも当てはまると思います。

于 2012-07-11T09:43:16.483 に答える
0

私の知る限り、List/Table/Tree-View-delegate のアイテムを表示するためにカスタム ウィジェットを使用することはできません。それらを編集に使用できますが、ビューモードで再描画以外のものが必要な場合は、かなり困惑します.

モデルイベントをリッスンし、アイテムウィジェットを動的に追加/削除する独自のコンテナウィジェットを用意することで、これを回避しました。かなり基本的な感じなので、本当に残念です。

その理由は、ビューが高速で多くのアイテムを表示できるはずであり、多くのウィジェットを使用すると高速ではないため、カスタムの再描画機能を許可することを選択したためである可能性があります (これにより、コンテナ ウィジェットが 1 つだけで、さまざまな領域にカスタム ペイントが適用されます。)

多分それを回避する方法があり、もしそうなら、私はそれについて聞いてうれしいです.

アップデート

イベントをキャッチする必要がある場合は、コンテナ ビューにイベント フィルタをインストールし、QListView::indexAtを使用して、イベントを送信する適切なアイテム/ウィジェット/デリゲートを見つけることができますか?

その後、mouseenter/leave でopenPersistentEditorと closePersistentEditor を使用して、編集を有効にできます。つまり、アイテムのカスタム ウィジェットを表示/閉じることができます。

于 2012-07-02T07:47:54.177 に答える