2015-06-30 11 views
0

У меня возникли проблемы с подключением действий контекстного меню в Qt. Я знаю, что есть много похожих вопросов, но я пока не нашел решения.Qt: Контекстное меню/соединение с параметрами

У меня есть серия участков, построенных с использованием QCustomplot.

Что я хочу сделать, так это создать контекстное меню, щелкнув правой кнопкой мыши по фону каждого графика, указав весь сигнал, присутствующий на графике. Нажав на это меню, соответствующий сигнал должен быть скрыт (если он отображается в данный момент) или сделан видимым (если скрыт).

Теперь я определил класс под названием PlotHandler которого я наклеить соответствующие части здесь ниже:

plotHandler.cpp

#include "plothandler.h" 

PlotHandler::PlotHandler(QStringList groupNames, int startIdx, QWidget *parent) : 
    QWidget(parent), scrolling(false), refreshing(true) 
{ 
    pPlot = new QCustomPlot(this); 
    pPlot->setContextMenuPolicy(Qt::CustomContextMenu); 
    connect(pPlot, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(contextMenuRequest(QPoint))); 
} 

void PlotHandler::contextMenuRequest(QPoint pos) 
{ 
    int i; 
    QMenu *menu = new QMenu(this); 
    for(i=0; i<pGroup->getDataLength(); i++) 
     { 
      QAction *menuEntry; 
      menuEntry = new QAction(pPlot->graph(i)->name(), this); 
      menuEntry->setProperty("graphIdx", i); 
      menu->addAction(menuEntry); 
      connect(menuEntry, SIGNAL(triggered()), this, SLOT(addRemoveGraph())); 
     } 
     menu->popup(pPlot->mapToGlobal(pos));  
} 

void PlotHandler::addRemoveGraph() 
{ 
    QAction *selectedSignal = qobject_cast<QAction *>(sender()); 
    int tmp = selectedSignal->property("graphIdx").toInt(); 

    if (pPlot->graph(tmp)->visible()) 
    { 
     pPlot->graph(tmp)->setVisible(false); 
    } 
    else 
    { 
     pPlot->graph(tmp)->setVisible(true); 
    } 
} 

plotHandler.h

class PlotHandler : public QWidget 
{ 
    Q_OBJECT 
public: 
    explicit PlotHandler(QStringList groupNames, int startIdx, QWidget *parent = 0); 
    QString groupRequested(); 

private: 
    QCustomPlot *pPlot; 

public slots: 
    void contextMenuRequest(QPoint pos); 
    void addRemoveGraph(); 
} 

Меню правильно показано с правильными вводами и когда я нажимаю на действие addRemoveGraph. В отладочном ответе возвращается следующее сообщение:

Понижение прекращено, поскольку оно вызвало исключение. Остановлен в thread 0 by: Exception at 0x5d6c2f9a, код: 0xc0000005: доступ для чтения нарушение при: 0x0, flags = 0x0.

пытается выполнить

int tmp = selectedSignal->property("graphIdx").toInt(); 

Может кто мне точку в правильном направлении?

Заранее спасибо

+0

Вы попробовали 'menu-> exec (QCursor :: pos());' вместо 'popup'? – jpo38

+0

Привет и спасибо за предложение. Я пытался, но ничего не изменилось. – tuspazio

+0

Выполняется ли 'addRemoveGraph()' при выборе пункта меню? Вы пробовали без вашего 'setProperty'? – jpo38

ответ

2

используется QObject::setProperty но QAction не имеет свойство с именем «graphIdx». Когда вы попытаетесь прочитать свойство «graphIdx» от QAction, вы всегда получите недопустимый QVariant.

int tmp = selectedSignal->property("graphIdx").toInt(); 
// tmp always is 0; 

Вы можете использовать QAction::setData, если вам нужно хранить только одно свойство. В противном случае используйте QObject::setProperty, чтобы установить нестандартное свойство на любом QObject. QAction - QObject.

0

Здесь ниже решение, которое решило проблему.

plotHandler.cpp

#include "plothandler.h" 

PlotHandler::PlotHandler(QStringList groupNames, int startIdx, QWidget *parent) : 
    QWidget(parent), scrolling(false), refreshing(true) 
{ 
    pPlot = new QCustomPlot(this); 
    pPlot->setContextMenuPolicy(Qt::CustomContextMenu); 
    connect(pPlot, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(contextMenuRequest(QPoint))); 
} 

void PlotHandler::contextMenuRequest(QPoint pos) 
{ 
    int i; 
    QMenu *menu = new QMenu(this); 
    for(i=0; i<pGroup->getDataLength(); i++) 
     { 
      QAction *menuEntry; 
      menuEntry = new QAction(pPlot->graph(i)->name(), this); 
      menuEntry->setData(i); 
      menu->addAction(menuEntry); 
     } 

    connect(menu, SIGNAL(triggered(QAction*)), this, SLOT(addRemoveGraph(QAction*)));  
    menu->popup(pPlot->mapToGlobal(pos));  
} 

void PlotHandler::addRemoveGraph(QAction *selectedSignal) 
{ 

    int tmp = selectedSignal->property("graphIdx").toInt(); 

    if (pPlot->graph(tmp)->visible()) 
    { 
     pPlot->graph(tmp)->setVisible(false); 
    } 
    else 
    { 
     pPlot->graph(tmp)->setVisible(true); 
    } 
    pPlot->replot(); 
} 

plotHandler.h

class PlotHandler : public QWidget 
{ 
    Q_OBJECT 
public: 
    explicit PlotHandler(QStringList groupNames, int startIdx, QWidget *parent = 0); 
    QString groupRequested(); 

private: 
    QCustomPlot *pPlot; 

public slots: 
    void contextMenuRequest(QPoint pos); 
    void addRemoveGraph(); 
} 

Спасибо всем за вашу помощь.

Смежные вопросы