Я огляделся и кажется, что проблема присутствует не только для виджета дерева, но и для других виджетов. Но в моем случае я нашел решение, хотя и неполное. Я добавляю действия в свой виджет дерева, чтобы при щелчке правой кнопкой мыши появлялось всплывающее окно с этими действиями. Однако, когда я добавляю элементы в виджет дерева и щелкаю по ним правой кнопкой мыши, появляется то же самое всплывающее окно. Что я хотел бы сделать, так это то, что когда вы щелкаете правой кнопкой мыши по виджету дерева, появляется всплывающее меню виджета дерева, а когда вы щелкаете правой кнопкой мыши по элементам, появляется другое соответствующее всплывающее меню. Кто-нибудь знает, как это сделать?
QTreeWidget контекстное меню
Ответы (4)
Сначала вы должны установить для политику контекстного меню значение CustomContextMenu
:
treeView->setContextMenuPolicy(Qt::CustomContextMenu);
Затем вы можете подключиться к сигналу QWidget::customContextMenuRequested(const QPoint&)
и показать свое контекстное меню.
Во-первых, настройте QTreeWidget для ответа (испускания сигнала) правой кнопкой мыши:
treeWidget->setContextMenuPolicy(Qt::CustomContextMenu);
Во-вторых, подключите сигнал к вашему слоту «MainWindow::prepareMenu»:
connect(treeWidget,&QTreeWidget::customContextMenuRequested,this,&MainWindow::prepareMenu);
В-третьих, создайте контекстное меню в слоте:
void MainWindow::prepareMenu( const QPoint & pos )
{
QTreeWidget *tree = treeWid;
QTreeWidgetItem *nd = tree->itemAt( pos );
qDebug()<<pos<<nd->text(0);
QAction *newAct = new QAction(QIcon(":/Resource/warning32.ico"), tr("&New"), this);
newAct->setStatusTip(tr("new sth"));
connect(newAct, SIGNAL(triggered()), this, SLOT(newDev()));
QMenu menu(this);
menu.addAction(newAct);
QPoint pt(pos);
menu.exec( tree->mapToGlobal(pos) );
}
QTreeWidgetItem *nd = tree->itemAt( pos );
!
- person zwcloud; 11.09.2018
Для тех, кто предпочитает больше использовать конструктор, вот еще один способ сделать это:
1) Установите политику контекстного меню в пользовательское контекстное меню.
Либо по коду:
ui->treeWidget->setContextMenuPolicy(Qt::CustomContextMenu);
или с помощью графического дизайнера щелкните виджет дерева и установите его с помощью Редактора свойств:
2) Создать функцию обработчика
В дизайнере щелкните правой кнопкой мыши виджет дерева и выберите опцию «Перейти к слоту...». Появится окно, подобное этому:
Нажмите на опцию «CustomContextMenuRequested (QPoint)». Функция-обработчик будет определена, объявлена и автоматически подключится.
void MainWindow::on_treeWidget_customContextMenuRequested(const QPoint &pos)
{
// this function will be called on right click
}
Этот шаг также можно выполнить, самостоятельно определив и подключив функцию слота.
3) Создайте параметры в контекстном меню.
Перейдите на вкладку редактора действий (обычно закреплена в нижней части конструктора). Добавьте действия, которые вы хотите иметь в контекстном меню, нажав новую кнопку в левом верхнем углу. Вы столкнетесь с таким интерфейсом:
Вы можете (необязательно) иметь всплывающую подсказку или значок для действия или сделать его доступным для проверки. Вы можете создать ярлык, например Ctrl+C, для действия копирования.
4) Создайте меню и запустите его
void MainWindow::on_treeWidget_customContextMenuRequested(const QPoint &pos)
{
QMenu menu(this); // add menu items
menu.addAction(ui->actionDelete);
menu.addEdit(ui->actionDelete);
...
ui->actionDelete->setData(QVariant(pos)); // if you will need the position data save it to the action
menu.exec( ui->treeWidget->mapToGlobal(pos) );
}
5) Создайте функции обработчика для каждого действия
Как и в шаге 2, либо создайте функцию слота и подключите ее вручную, либо щелкните правой кнопкой мыши действие, выберите опцию «Перейти к слотам…» и выберите слот triggered().
6) Наконец, примените свою логику в функции слота.
void MainWindow::on_actionEdit_triggered()
{
QTreeWidgetItem *clickedItem = ui->treeWidget->itemAt(ui->actionDelete->data().toPoint());
// your logic
}
Взгляните на перегрузку QAbstractItemModel и предоставление собственного OnContextMenuRequested. С помощью этой функции вы можете создать разные контекстные меню для разных элементов.
Вот укороченный псевдо-код одного из моих проектов, который может быть полезен:
void MyModel::OnContextMenuRequested(const QModelIndex& index, const QPoint& globalPos)
{
// find 'node' corresponding to 'index'
vector<pair<string,BaseNode*> > actions = node->GetActions(true);
if(actions.size()==0) return;
// the ptr list helps us delete the actions
boost::ptr_list<QObject> actionPtrList;
QList<QAction*> qtActions;
for(unsigned int i=0;i<actions.size();i++)
{
QAction* act = new QAction(actions[i].first.c_str(),NULL);
act->setData(qVariantFromValue(actions[i].second));
actionPtrList.push_back(act);
qtActions.append(act);
}
// create and show the context menu
QMenu *menu = new QMenu("Item actions",NULL);
actionPtrList.push_back(menu);
QAction* act = menu->exec(qtActions,globalPos);
if(act==NULL) return;
// act on the resulting action 'act'
}