Здравствуйте! Пытаюсь создать контекстное меню, которое будет вызываться при нажатии правой кнопки мыши. Проблема в том, что я создал класс, в котором собираюсь реализовать весь список контекстного меню, но теперь у меня не получается добавить его объект в основную программу, где я обрабатываю нажатие кнопок мыши. Подскажите, что я делаю неправильно?
Создаю класс для меню.
h - файл
#include <QWidget>
#include <QMenu>
#include <QDebug>
#include <QInputEvent>
class ContextMenu : public QWidget
{
Q_OBJECT
public:
ContextMenu(QWidget* parent = 0);
~ContextMenu()
{
// delete menu;
// delete widget;
qDebug() << "Destructor of ContextMenu class";
}
protected:
void contextMenuEvent(QContextMenuEvent* event) override;
private slots:
void slotPropertiesGraph();
void slotItem1();
void slotItem2();
void slotItem3();
private:
QMenu *menu;
QWidget *widget;
QAction *propGrahp;
QAction *item1;
QAction *item2;
QAction *item3;
};
cpp - файл
#include "contextmenu.h"
ContextMenu::ContextMenu(QWidget* parent) : QWidget(parent)
{
// widget = new QWidget;
// widget->setContextMenuPolicy(Qt::CustomContextMenu);
// parent->setContextMenuPolicy(Qt::CustomContextMenu);
menu = new QMenu(this);
propGrahp = new QAction("Prorerties", this);
item1 = new QAction("Item1", this);
item2 = new QAction("Item2", this);
item3 = new QAction("Item3", this);
menu->addAction(propGrahp);
menu->addAction(item1);
menu->addAction(item2);
menu->addAction(item3);
connect(propGrahp, &QAction::triggered, this, &ContextMenu::slotPropertiesGraph);
connect(item1, &QAction::triggered, this, &ContextMenu::slotItem1);
connect(item2, &QAction::triggered, this, &ContextMenu::slotItem2);
connect(item3, &QAction::triggered, this, &ContextMenu::slotItem3);
qDebug() << "Construtor of ContextMenu class";
}
void ContextMenu::contextMenuEvent(QContextMenuEvent* event)
{
menu->exec(event->globalPos());
qDebug() << "contextMenuEvent";
// connect(widget, &QWidget::customContextMenuRequested, this, &ContextMenu::slotCustomMenuRequested);
}
void ContextMenu::contextMenuEvent(QContextMenuEvent* event)
{
menu->exec(event->globalPos());
qDebug() << "contextMenuEvent";
// connect(widget, &QWidget::customContextMenuRequested, this, &ContextMenu::slotCustomMenuRequested);
}
void ContextMenu::slotPropertiesGraph()
{
qDebug() << "properties graph!!!";
}
void ContextMenu::slotItem1()
{
qDebug() << "Item1";
}
void ContextMenu::slotItem2()
{
qDebug() << "Item2";
}
void ContextMenu::slotItem3()
{
qDebug() << "Item3";
}
Функция, в которой я обрабатываю нажатие кнопок мыши. При нажатии на правую кнопку мыши должно вызываться созданное меню в точке, где находится курсор мыши.
void MainWindow::mousePress(QMouseEvent *event)
{
if (event->button() == Qt::LeftButton)
{
posCursor = event->pos();
QWidget *widFocus = QApplication::focusWidget();
for (QCustomPlot *w : widgetList)
{
if (widFocus->objectName() == w->objectName())
{
sctRect = new SelectedRect(QRubberBand::Rectangle, w);
sctRect->setGeometry(QRect(posCursor, QSize()));
sctRect->show();
qDebug() << "press";
qDebug() << "pos: " << event->localPos();
}
}
}
else if (event->button() == Qt::RightButton)
{
// ui->osc->setContextMenuPolicy(Qt::ActionsContextMenu);
// ui->spectrum->setContextMenuPolicy(Qt::ActionsContextMenu);
cMenu = new ContextMenu(ui->osc);
cMenu->setVisible(true);
qDebug() << "RightButton";
}
}
Привет! Можешь скинуть проект целиком?
А вообще вот я накидал простенький пример:
MainWindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
private slots:
void customContextMenuRequestedSlot();
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
MainWindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
this->setContextMenuPolicy(Qt::CustomContextMenu);
connect(this, &MainWindow::customContextMenuRequested, this, &MainWindow::customContextMenuRequestedSlot);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::customContextMenuRequestedSlot()
{
QMenu* menu = new QMenu(this);
QAction* closeAction = new QAction(("Close"), this);
connect(closeAction, &QAction::triggered, this, &MainWindow::close);
menu->addAction(closeAction);
menu->popup(QCursor::pos());
}
@aveal Проект я добавил, если еще нужно. А на счет кода, то я сделал класс, в конструкторе которого все это создаю и в него же добавил строку для закрепления меню к позиции курсора (показана ниже). Но мне непонятна суть создания контекстного меню через строку setContextMenuPolicy(Qt::CustomContextMenu), потому что я просто все сделал в конструкторе класса.
menu->popup(QCursor::pos());
Еще появился вопрос по поводу того, как из конструктора контекстного меню брать результат работы тех или иных функций. Например, я хочу сделать на правую кнопку мыши вызов меню, в котором будут всякие разные поля по работе с графиком такие, как cut, properties, zoom, а чтобы не нагружать mainwindow.cpp я хочу всю логику, которая связана с настройкой графика, прописать в отдельном классе (ContextMenu), но как мне потом вставлять тот же измененный цвет графика в обработку правой кнопки мыши уже в сам mainwindow.cpp я не знаю.
Чтобы лучше было понятно о чем я говорю, добавил картинки. На них есть контекстное меню с полем properties, которое вызывает новую форму, а она все настройки после нажатия OK передает графику.
Может у кого-то есть исходники с простенькой программкой, в которой создается что-то похожее и при этом не запихивается все в один файл mainwindow? Потому что у меня идея только создать кучу переменных, а потом через какие-нибудь сетторы все это брать.
Еще есть идея сделать под каждую настройку сигнал в классе ContextMenu, а уже в главном файле под каждый сигнал сделать соответствующий слот.
@rodion-2 Либо все настройки упаковать в структуру, например, и пробрасывать одним слотом, либо через get().




