15

QTableviewと を使用して 1 つのテーブルを作成しましたQAbstractTableModel。セルの 1 つで、そのセルの右隅に1 つのヘルプ ボタンを追加したいと考えています。

これを達成する方法はありますか?

4

6 に答える 6

30

そのためには、独自のデリゲートを実装する必要があります。

Qt では、データ、モデル、ビューの他に、デリゲートがあります。それらは入力機能を提供し、必要なものであるビュー内の「特別な」アイテムのレンダリングも担当します。

Qt doc には、これら (キーワード: ) に関する十分な説明があり、いくつかの例をhereおよびhereModel/View programmingで見つけることもできます。

また(少し話題から外れますが、これを指摘しておく必要があると思います)、通常の を使用すると、その関数を使用QTableWidgetして任意のセルに何でも挿入できsetCellWidget()ます。

UPD

これは Qt のドキュメントからわずかに変更された例です (私は Qt のモデル/ビュー関連が苦手なので、このコードで私を苦しめないでください)。右側の各セルにボタンを描画し、セルのクリックイベントをキャッチして、クリックが「ボタン」上にあるかどうかを確認し、それに応じて反応します。

おそらくこれは最善の方法ではありませんが、前述したように、私は Qt のモデルとビューがあまり得意ではありません。

createEditor()物事を正しく行い、適切な編集を可能にするには、 、setEditorData()およびsetModelData()関数も実装する必要があります。

すべてのセルではなく特定のセルに要素を描画するには、paint()関数に条件を追加するだけです (モデル インデックスを引数として取得するため、描画しているセルを常に把握し、それに応じて描画できます)。


デリゲート.h:

class MyDelegate : public QItemDelegate
{
    Q_OBJECT

public:
    MyDelegate(QObject *parent = 0);
    void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const;
    bool editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index);
};

デリゲート.cpp:

 #include <QtGui>
 #include "delegate.h"

 MyDelegate::MyDelegate(QObject *parent)
     : QItemDelegate(parent)
 {
 }


 void MyDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
 {
     QStyleOptionButton button;
     QRect r = option.rect;//getting the rect of the cell
     int x,y,w,h;
     x = r.left() + r.width() - 30;//the X coordinate
     y = r.top();//the Y coordinate
     w = 30;//button width
     h = 30;//button height
     button.rect = QRect(x,y,w,h);
     button.text = "=^.^=";
     button.state = QStyle::State_Enabled;

     QApplication::style()->drawControl( QStyle::CE_PushButton, &button, painter);
 }

 bool MyDelegate::editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index)
 {
     if( event->type() == QEvent::MouseButtonRelease )
     {
         QMouseEvent * e = (QMouseEvent *)event;
         int clickX = e->x();
         int clickY = e->y();

         QRect r = option.rect;//getting the rect of the cell
         int x,y,w,h;
         x = r.left() + r.width() - 30;//the X coordinate
         y = r.top();//the Y coordinate
         w = 30;//button width
         h = 30;//button height

         if( clickX > x && clickX < x + w )
             if( clickY > y && clickY < y + h )
             {
                 QDialog * d = new QDialog();
                 d->setGeometry(0,0,100,100);
                 d->show();
             }
     }

     return true;
 }

main.cpp

#include "delegate.h"

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);

    QStandardItemModel model(4, 2);
    QTableView tableView;
    tableView.setModel(&model);

    MyDelegate delegate;
    tableView.setItemDelegate(&delegate);

    tableView.horizontalHeader()->setStretchLastSection(true);
    tableView.show();
    return app.exec();
}

結果は次のようになります。

結果

于 2012-08-02T13:03:32.077 に答える
7

setIndexWidget は私にとってはうまくいきました。例:

QPushButton* helpButton = new QPushButton("Help");

tableView->setIndexWidget(model->index(position,COLUMN_NUMBER), helpButton);

ボタンを追加して、それをクリックして何かをしたいだけの場合は、setIndexWidget() を使用してボタンを追加するとうまくいきます。面倒なペイント メソッドやデリゲートの実装は必要ないと思います。

于 2016-01-29T12:21:29.763 に答える
0

私は解決策を得ました..古いペイント方法:

void MyDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
 {
     QStyleOptionButton button;
     QRect r = option.rect;//getting the rect of the cell
     int x,y,w,h;
     x = r.left() + r.width() - 30;//the X coordinate
     y = r.top();//the Y coordinate
     w = 30;//button width
     h = 30;//button height
     button.rect = QRect(x,y,w,h);
     button.text = "=^.^=";
     button.state = QStyle::State_Enabled;

     QApplication::style()->drawControl( QStyle::CE_PushButton, &button, painter);
 }

これが更新されたpaint()メソッドです。

void MyDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
 {
         QItemDelegate::paint(painter, option, index);
  if(index.row()==8)//since i have to make it display only at (8,0) position .
 {
  if(index.column()==0)
  {
     QStyleOptionButton button;
     QRect r = option.rect;//getting the rect of the cell
     int x,y,w,h;
     x = r.left() + r.width() - 20;//the X coordinate
     y = r.top();//the Y coordinate
     w = 15;//button width(based on the requirement)
     h = 15;//button height(based on the requirement)
  button.icon= QIcon(QString::fromUtf8("Resources/HelpIcon.png"));
  button.iconSize = QSize(20,20);
     button.rect = QRect(x,y,w,h);
     button.text = "";//no text . since if text will be given then it will push the icon to left side based on the coordinates .
     button.state = QStyle::State_Enabled;

     //QApplication::style()->drawControl( QStyle::CE_PushButton, &button, painter);

  QApplication::style()->drawControl( QStyle::CE_PushButtonLabel, &button, painter);//To make the Button transparent .

  }
  }
}
于 2012-08-09T07:17:22.953 に答える
0

ビューがセルを描画する場合、paint()セルのコンテンツを描画する方法、内容、場所に関する情報を使用してデリゲートの関数を呼び出します。デフォルトのデリゲートは、Qt::DisplayRoleテキストとselectionState.

デリゲートを置き換えると、デフォルトの動作が完全に置き換えられます。好きなように描画できます。テキストが必要な場合は、それを描画するように手配する必要があります。自分で行うことも、標準の C++ メカニズムを使用して、最初にデフォルトの描画コードを呼び出してから上から描画することもできます。私のメソッドQItemDelegate::paint(painter, option, index);の先頭に追加すると機能します。paint()

于 2012-08-08T05:53:06.170 に答える