How to Create a Custom Context Menu For QTableView
-
Try the following:
main.cpp
#include <QtGui/QApplication> #include "widget.h" int main(int argc, char *argv[]) { QApplication a(argc, argv); Widget w; w.show(); return a.exec(); }
widget.h
#ifndef WIDGET_H #define WIDGET_H #include <QtGui/QWidget> class QTableView; class Widget : public QWidget { Q_OBJECT public: Widget(QWidget *parent = 0); ~Widget(); public slots: void customMenuRequested(QPoint pos); private: QTableView *table; }; #endif // WIDGET_H
widget.cpp
#include <QtGui> #include "widget.h" Widget::Widget(QWidget *parent) : QWidget(parent) { QVBoxLayout *l=new QVBoxLayout(this); table=new QTableView(this); table->setContextMenuPolicy(Qt::CustomContextMenu); connect(table, SIGNAL(customContextMenuRequested(QPoint)), SLOT(customMenuRequested(QPoint))); l->addWidget(table); } Widget::~Widget(){} void Widget::customMenuRequested(QPoint pos){ QModelIndex index=table->indexAt(pos); QMenu *menu=new QMenu(this); menu->addAction(new QAction("Action 1", this)); menu->addAction(new QAction("Action 2", this)); menu->addAction(new QAction("Action 3", this)); menu->popup(table->viewport()->mapToGlobal(pos)); }
Basically, we tell our QTableView that we want to use a custom context menu by calling the setContextMenuPolicy() method with the arguments Qt::CustomContextMenu. We then create a slot customMenuRequested() and connect it to the customContextMenuRequested() signal. This signal has a QPoint as its argument which is the position at which the request was made relative to the table. This position is useful because we can use it to discover which table cell was clicked on (if any) using the indexAt() method and also to position our menu correctly relative to the mouse.
Hope this helps ;o)
[edit: updated coding tags SGaist]
-
-
Use the same JazzyCamel's example. In Widget.cpp
Instead of,
table->setContextMenuPolicy(Qt::CustomContextMenu); connect(table, SIGNAL(customContextMenuRequested(QPoint)), SLOT(customMenuRequested(QPoint)));
Change it to
table->horizontalHeader-> setContextMenuPolicy(Qt::CustomContextMenu); connect(table->horizontalHeader(), SIGNAL(customContextMenuRequested(QPoint)), SLOT(customMenuRequested(QPoint)));
Hope you get it..
[edit: updated coding tags SGaist]
-
Rochi got there just as I was finishing the following and is exactly right, as both QTableView and QHeaderView inherit QAbstractItemView the method is the same:
widget.h
#ifndef WIDGET_H #define WIDGET_H #include <QtGui/QWidget> class QStandardItemModel; class QTableView; class Widget : public QWidget { Q_OBJECT public: Widget(QWidget *parent = 0); ~Widget(); public slots: void customMenuRequested(QPoint pos); void customHeaderMenuRequested(QPoint pos); private: QStandardItemModel *model; QTableView *table; }; #endif // WIDGET_H
widget.cpp
#include <QtGui> #include "widget.h" Widget::Widget(QWidget *parent) : QWidget(parent) { model=new QStandardItemModel(10,10,this); QVBoxLayout *l=new QVBoxLayout(this); table=new QTableView(this); table->setModel(model); table->setContextMenuPolicy(Qt::CustomContextMenu); connect(table, SIGNAL(customContextMenuRequested(QPoint)), SLOT(customMenuRequested(QPoint))); table->horizontalHeader()->setContextMenuPolicy(Qt::CustomContextMenu); connect(table->horizontalHeader(), SIGNAL(customContextMenuRequested(QPoint)), SLOT(customHeaderMenuRequested(QPoint))); l->addWidget(table); } Widget::~Widget() { } void Widget::customMenuRequested(QPoint pos){ QModelIndex index=table->indexAt(pos); QMenu *menu=new QMenu(this); menu->addAction(new QAction("Action 1", this)); menu->addAction(new QAction("Action 2", this)); menu->addAction(new QAction("Action 3", this)); menu->popup(table->viewport()->mapToGlobal(pos)); } void Widget::customHeaderMenuRequested(QPoint pos){ int column=table->horizontalHeader()->logicalIndexAt(pos); QMenu *menu=new QMenu(this); menu->addAction(new QAction("Header Action 1", this)); menu->addAction(new QAction("Header Action 2", this)); menu->addAction(new QAction("Header Action 3", this)); menu->popup(table->horizontalHeader()->viewport()->mapToGlobal(pos)); }
Hope this answers your question ;o)
[edit: updated coding tags SGaist]