QTableview
と を使用して 1 つのテーブルを作成しましたQAbstractTableModel
。セルの 1 つで、そのセルの右隅に1 つのヘルプ ボタンを追加したいと考えています。
これを達成する方法はありますか?
そのためには、独自のデリゲートを実装する必要があります。
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();
}
結果は次のようになります。
setIndexWidget は私にとってはうまくいきました。例:
QPushButton* helpButton = new QPushButton("Help");
tableView->setIndexWidget(model->index(position,COLUMN_NUMBER), helpButton);
ボタンを追加して、それをクリックして何かをしたいだけの場合は、setIndexWidget() を使用してボタンを追加するとうまくいきます。面倒なペイント メソッドやデリゲートの実装は必要ないと思います。
私は解決策を得ました..古いペイント方法:
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 .
}
}
}
ビューがセルを描画する場合、paint()
セルのコンテンツを描画する方法、内容、場所に関する情報を使用してデリゲートの関数を呼び出します。デフォルトのデリゲートは、Qt::DisplayRole
テキストとselectionState
.
デリゲートを置き換えると、デフォルトの動作が完全に置き換えられます。好きなように描画できます。テキストが必要な場合は、それを描画するように手配する必要があります。自分で行うことも、標準の C++ メカニズムを使用して、最初にデフォルトの描画コードを呼び出してから上から描画することもできます。私のメソッドQItemDelegate::paint(painter, option, index);
の先頭に追加すると機能します。paint()