我已經使用QTableview和QAbstractTableModel創建了一個表。 在其中一個單元格中,我想添加一個幫助按鈕(該單元格的右下角)。將按鈕添加到QTableview
有沒有辦法達到上述目的?
我已經使用QTableview和QAbstractTableModel創建了一個表。 在其中一個單元格中,我想添加一個幫助按鈕(該單元格的右下角)。將按鈕添加到QTableview
有沒有辦法達到上述目的?
你將不得不爲你實現你自己的委託。
在Qt中,除了數據,模型和視圖外,您還有代表。他們提供輸入功能,他們還負責在View中呈現「特殊」項目,這正是您所需要的。
Qt doc對這些(關鍵字:Model/View programming
)有很好的覆蓋率,您還可以找到一些示例here和here。
另外(有點偏離主題,但我想我應該指出這一點),如果你使用普通的QTableWidget
,你可以插入任何與它的setCellWidget()
功能的單元格中的任何東西。
UPD
這裏是Qt的文檔(我與模型/視圖東西吸Qt的,所以不要打我辛苦爲這個代碼)一稍微變形例。它會在右側的每個單元格中繪製一個按鈕,並捕獲單元格中的單擊事件以檢查單擊是否在「按鈕」上,並相應地作出反應。
也許這不是最好的辦法,但正如我所提到的,我對Qt的模型和視圖並不太滿意。
要做正確的事情並允許正確編輯,您還需要執行createEditor()
,setEditorData()
和setModelData()
函數。
要在特定的單元格而不是所有單元格中繪製您的東西,只需在paint()
函數中添加一個條件(請注意,它將模型索引作爲參數,因此您始終可以知道您正在繪製的單元格,以及油漆相應)。
delegate.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);
};
delegate.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();
}
結果將是這樣的:
當視圖要畫它調用委託的paint()提供了關於如何的一些信息功能的細胞,什麼,在哪裏畫的內容細胞。默認的委託只是繪製Qt :: DisplayRole文本和選擇狀態。如果你替換委託,那麼你完全替換了默認行爲:你可以繪製任何你喜歡的。如果你想要的文字,那麼你需要安排繪製它。你可以自己做,或者使用標準的C++機制,你可以先調用默認的繪圖代碼,然後在頂部繪製。 它添加QItemDelegate :: paint(畫家,選項,索引)後工作;在我的paint()方法的開始。
我得到了解決.. 舊漆方法:
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 .
}
}
}
setIndexWidget爲我工作。 例子:
QPushButton* helpButton = new QPushButton("Help");
tableView->setIndexWidget(model->index(position,COLUMN_NUMBER), helpButton);
如果你只是想添加一個按鈕,做的是點擊的東西,添加使用setIndexWidget()按鈕正常工作。我相信我們不需要繁瑣的繪畫方法或實施代表。
我有一個解決方案,沒有任何複雜的重新發明整個油漆過程。 我有一個TableView,我在每一行都有一個按鈕。 請注意,在我的情況下,for循環遍歷每一行。
QSignalMapper *signalMapper = new QSignalMapper(this);
for(int i=0; i<rows.length(); i++) { //replace rows.length with your list or vector which consists of the data for your rows.
//do something with your data for normal cells...
auto item = model->index(i, COLUMN_FOR_WHATEVER_YOU_WANT);
model->setData(item, QVariant::fromValue(yourObject.getSpecificInformation()));
//make new button for this row
item = model->index(i, COLUMN_BUTTON);
QPushButton *cartButton = new QPushButton("Add");
ui->table_view->setIndexWidget(item, cartButton);
signalMapper->setMapping(cartButton, i);
connect(cartButton, SIGNAL(clicked(bool)), signalMapper, SLOT(map()));
}
connect(signalMapper, SIGNAL(mapped(int)), this, SLOT(doSomething(int)));
然後,您將自動獲取用戶單擊該按鈕所在行的索引。 你只需要使自己的插槽:
private SLOTS:
void doSomething(int row);
如果您有特殊的細胞,它的工作類似。
請注意,我並不關心這個例子中的內存泄漏,而且我不完全知道如果你更新你的TableView會發生什麼......(它工作正常,但它可能不會刪除舊的按鈕 - 當新的創建時,指針)
在Qt5中,你甚至不需要使用QSignalMapper;您可以將按鈕的信號連接到您選擇的外殼的拉姆達。 – 2016-07-27 09:43:27
我正在使用QTableview。 我想把這個按鈕放在一個特定的單元格中(該單元格的右下角).. 請問您可以分享一些代碼嗎? thankx in adv .. – Learner 2012-08-02 18:45:10
@vikuseth,更新了我的回答 – SingerOfTheFall 2012-08-03 06:49:22
@vikuseth,Oo它對我來說總是可見的。 – SingerOfTheFall 2012-08-04 18:12:53