2

QList ウィジェット用の QStyledItemDelegate があります。

class MappingDisplayWidgetDelegate: public QStyledItemDelegate
{
    Q_OBJECT
public:
    MappingDisplayWidgetDelegate(QObject *parent=NULL);
    virtual void paint ( QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index ) const;
    virtual QSize sizeHint ( const QStyleOptionViewItem & option, const QModelIndex & index ) const;
};

そして、ペイントメソッドは次のようになります:

void MappingDisplayWidgetDelegate::paint ( QPainter * painter,
                                           const QStyleOptionViewItem & option,
                                           const QModelIndex & index ) const
{
    if (option.state & QStyle::State_Selected)
        painter->fillRect(option.rect, option.palette.highlight());
    else if (option.state & QStyle::State_MouseOver)
        painter->fillRect(option.rect, option.palette.midlight());


    QFontMetrics fm(option.font);

    QString filename = index.data(Qt::DisplayRole).toString();

    QRect outline = option.rect;
    int outmid = outline.center().y();

    QRect fnBound = fm.boundingRect(filename);
    int fnBoundMid = fnBound.center().y();
    fnBound.moveLeft(outline.left());
    fnBound.translate(0, outmid - fnBoundMid);

    painter->drawText(fnBound, Qt::AlignVCenter | Qt::AlignLeft, filename);

}

これで動作しますが、State_Selected と State_MouseOver の処理では、既定のリストと同じ結果が得られません。上記のコードのスクリーン ショット (私は Win7 システムで実行しています) を左側に、標準の QListWidget を右側に示します。QListWidget には素敵なグラデーションがあることがわかりますが、私のアイテムには単純な色しかありません。

ここに画像の説明を入力

標準のウィジェットに適切に一致するようにアイテムをペイントしたいのですが、どうすればよいかわかりません。必要な情報を提供するオプションが何も表示されません。

追加するために編集: これはややおもちゃの例であることに注意してください。実際のコードには、1 つの文字列以外にもたくさんのものがあり、適切な (そして機能する) sizeHint 関数があります。これは、問題を示すための単なるおもちゃです。

4

3 に答える 3

2

その要素を描画するためのソース コードでは、次の呼び出しが行われます。

// draw the background
proxy()->drawPrimitive(PE_PanelItemViewItem, opt, p, widget);

次のようなことをしたいと思うかもしれません。

style().drawPrimitive(QStyle::PE_PanelItemViewItem, option, painter, NULL);

option適切な長方形のターゲットを取得するには、パラメーターをいじる必要がある場合があります。残念ながら、私が現在使用しているコンピューターは、これをテストするように設定されていないため、YMMV.

于 2012-09-24T16:58:36.867 に答える
1

同じ質問がありました。完全にカスタムのペイント機能が必要でしたが、組み込みのプリティ セレクション ペイントを利用したかったのです。以下のコードを試してみましたが、これまでのところ、悪影響を与えることなくうまく機能することがわかりました。

void MassIndexItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex& index) const {
    QStyledItemDelegate::paint(painter, option, QModelIndex());
    //Above, note that rather than passing >index< to the inherited function, I pass a default, invalid index.
    //Since my model's data() function returns an empty QVariant for invalid indexes,
    //I get the default selection painting, but no other data is painted in any way.

    //Below, I can do whatever painting I want and it will show up on top of the pretty selection paint
    painter->drawEllipse(option.rect);
}
于 2016-02-26T00:35:27.753 に答える
0

優れたソリューションではありませんが、これを使用可能なソリューションとして詳しく説明します。

アイテムのDisplayRoleに何も入れない場合は、基になるQStyledItemDelegate :: paintルーチンを呼び出すことができます。これにより、適切な背景が描画されます。

void MappingDisplayWidgetDelegate::paint ( QPainter * painter,
                                           const QStyleOptionViewItem & option,
                                           const QModelIndex & index ) const
{
    QStyledItemDelegate::paint(painter, option, index);

    QFontMetrics fm(option.font);

    QString filename = index.data(Qt::UserRole).toString();

    QRect outline = option.rect;
    int outmid = outline.center().y();

    QRect fnBound = fm.boundingRect(filename);
    int fnBoundMid = fnBound.center().y();
    fnBound.moveLeft(outline.left());
    fnBound.translate(0, outmid - fnBoundMid);

    painter->drawText(fnBound, Qt::AlignVCenter | Qt::AlignLeft,
                      filename);
}

私はこれが好きではなく、デイブの提案をすぐに試してみるつもりですが、行き詰まった場合、これはうまくいくようです。欠点は、DisplayRoleを使用できないため、QListWidgetでfindItemsを使用できないことを意味します。

于 2012-09-24T17:20:51.870 に答える