Question

I have a program that plots some simple data using MathGL, and displays it using a QMainWindow:

main.cpp

#include <QtGui/QApplication>
#include "mainwindow.h"

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
    w.show();

   return a.exec();
}

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
   Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
     ~MainWindow();

private slots:
    void on_pushButton_clicked();

private:
    Ui::MainWindow *ui;
};

#endif // MAINWINDOW_H

mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "plot.h"
#include <armadillo>

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::on_pushButton_clicked()
{
    arma::mat Data;

    //String to open window to get fileName
    QString DataFile = QFileDialog::getOpenFileName(this, tr("Open File"), "/home/", tr("Text Files   (*.txt)"));


    plot test(DataFile);
}

plot.h

#ifndef PLOT_H
#define PLOT_H

#include <QObject>
#include <armadillo>
#include <mgl2/data.h>
#include <mgl2/mgl.h>
#include <mgl2/qmathgl.h>
#include <mgl2/qt.h>
#include <mgl2/wnd.h>
#include <mgl2/canvas_wnd.h>
#include <QMainWindow>
#include <QtCore>

class plot : public QObject
{
    Q_OBJECT
public:
    explicit plot(QObject *parent = 0);
    plot(QString);

signals:

public slots:

};

#endif // PLOT_H

plot.cpp

#include "plot.h"

#define MGL_MAX_LINES   (INT_MAX-1000)
#if !defined(WIN32) && !defined(__APPLE__)
#include <X11/Xlib.h>
#endif

#define TR  QObject::tr
QMenu *mglMakeMenu(QMainWindow *Wnd, QMathGL *QMGL, QSpinBox *&tet, QSpinBox *&phi)
{
QAction *a;
QMenu *o, *oo;
QToolBar *bb;

QMenu *popup = new QMenu(Wnd);
// file menu
{
    o = Wnd->menuBar()->addMenu(TR("&File"));
    oo = new QMenu(TR("&Export as 2D ..."),Wnd);
    oo->addAction(TR("PNG"), QMGL, SLOT(exportPNG()),Qt::ALT+Qt::Key_P);
    oo->addAction(TR("JPEG"), QMGL, SLOT(exportJPG()),Qt::ALT+Qt::Key_J);
    o->addMenu(oo);     popup->addMenu(oo);

    o->addSeparator();
    a = new QAction(QPixmap(), TR("Print &graphics"), Wnd);
    Wnd->connect(a, SIGNAL(triggered()), QMGL, SLOT(print()));
    a->setToolTip(TR("Open printer dialog and print graphics\t(CTRl+P)"));
    a->setShortcut(Qt::CTRL+Qt::Key_P); o->addAction(a);
    o->addSeparator();
    o->addAction(TR("&Close"), Wnd, SLOT(close()), Qt::CTRL+Qt::Key_W);
}
// graphics menu
{
    bb = new QToolBar(TR("Graphics"),Wnd);
    Wnd->addToolBar(Qt::TopToolBarArea, bb);
    o = Wnd->menuBar()->addMenu(TR("&Graphics"));
    a = new QAction(QPixmap(":/usr/include/mathgl-2.1.2/include/xpm/rotate.xpm"), TR("&Rotate by  mouse"), Wnd);
    a->setCheckable(true);
    Wnd->connect(a, SIGNAL(toggled(bool)), QMGL, SLOT(setRotate(bool)));
    Wnd->connect(QMGL, SIGNAL(rotateChanged(bool)), a, SLOT(setOn(bool)));
    a->setToolTip(TR("Switch on/off mouse handling of the graphics\n(rotation, shifting, zooming and perspective)."));
    bb->addAction(a);
    a = new QAction(QPixmap(":/usr/include/mathgl-2.1.2/include/xpm/zoom_in.xpm"), TR("&Zoom by mouse"), Wnd);
    a->setCheckable(true);
    Wnd->connect(a, SIGNAL(toggled(bool)), QMGL, SLOT(setZoom(bool)));
    Wnd->connect(QMGL, SIGNAL(zoomChanged(bool)), a, SLOT(setOn(bool)));
    a->setToolTip(TR("Switch on/off mouse zoom of selected region."));
    bb->addAction(a);
    o->addSeparator();
    a = new QAction(QPixmap(":/usr/include/mathgl-2.1.2/include/xpm/zoom_out.xpm"), TR("Res&tore"), Wnd);
    Wnd->connect(a, SIGNAL(triggered()), QMGL, SLOT(restore()));
    a->setToolTip(TR("Restore default graphics rotation, zoom and perspective (Alt+Space)."));
    a->setShortcut(Qt::ALT+Qt::Key_Space);
    o->addAction(a);    bb->addAction(a);   popup->addAction(a);
    bb->addSeparator();
    a = new QAction(QPixmap(":/usr/include/mathgl-2.1.2/include/xpm/ok.xpm"), TR("Re&draw"), Wnd);
    Wnd->connect(a, SIGNAL(triggered()), QMGL, SLOT(update()));
    a->setToolTip(TR("Execute script and redraw graphics (F5)."));
    a->setShortcut(Qt::Key_F5);
    o->addAction(a);    bb->addAction(a);   popup->addAction(a);
    a = new QAction(TR("&Adjust size"), Wnd);
    Wnd->connect(a, SIGNAL(triggered()), QMGL, SLOT(adjust()));
    a->setToolTip(TR("Change canvas size to fill whole region (F6)."));
    a->setShortcut(Qt::Key_F6);     o->addAction(a);
    a = new QAction(QPixmap(":/usr/include/mathgl-2.1.2/include/xpm/copy.xpm"), TR("&Copy plot"), Wnd);
    Wnd->connect(a, SIGNAL(triggered()), QMGL, SLOT(copy()));
    a->setToolTip(TR("Copy graphics to clipboard (CTRl+Shift+G)."));
    a->setShortcut(Qt::CTRL+Qt::SHIFT+Qt::Key_G);
    o->addAction(a);        bb->addAction(a);   popup->addAction(a);

    bb->addSeparator();
    oo = new QMenu(TR("Primitives ..."),Wnd);

    a = new QAction(QPixmap(":/usr/include/mathgl-2.1.2/include/xpm/line.xpm"), TR("Add line"), Wnd);
    Wnd->connect(a, SIGNAL(triggered()), QMGL, SLOT(addLine()));
    Wnd->connect(QMGL, SIGNAL(usePrimChanged(bool)), a, SLOT(setVisible(bool)));
    a->setToolTip(TR("Add line which properties can be changed later by mouse."));
    bb->addAction(a);   oo->addAction(a);

    a = new QAction(QPixmap(":/usr/include/mathgl-2.1.2/include/xpm/mark_a.xpm"), TR("Add mark"), Wnd);
    Wnd->connect(a, SIGNAL(triggered()), QMGL, SLOT(addMark()));
    Wnd->connect(QMGL, SIGNAL(usePrimChanged(bool)), a, SLOT(setVisible(bool)));
    a->setToolTip(TR("Add marker which properties can be changed later by mouse."));
    bb->addAction(a);   oo->addAction(a);

    a = new QAction(QPixmap(":/usr/include/mathgl-2.1.2/include/xpm/text.xpm"), TR("Add text"), Wnd);
    Wnd->connect(a, SIGNAL(triggered()), QMGL, SLOT(addText()));
    Wnd->connect(QMGL, SIGNAL(usePrimChanged(bool)), a, SLOT(setVisible(bool)));
    a->setToolTip(TR("Add text which properties can be changed later by mouse."));
    bb->addAction(a);   oo->addAction(a);
    o->addMenu(oo);

    bb->addSeparator();
    tet = new QSpinBox(Wnd);    tet->setWrapping(true);
    bb->addWidget(tet); tet->setRange(-180, 180);   tet->setSingleStep(10);
    Wnd->connect(tet, SIGNAL(valueChanged(int)), QMGL, SLOT(setTet(int)));
    Wnd->connect(QMGL, SIGNAL(tetChanged(int)), tet, SLOT(setValue(int)));
    tet->setToolTip(TR("Set value of \\theta angle."));
    bb->addSeparator();
    phi = new QSpinBox(Wnd);    phi->setWrapping(true);
    bb->addWidget(phi); phi->setRange(-180, 180);   phi->setSingleStep(10);
    Wnd->connect(phi, SIGNAL(valueChanged(int)), QMGL, SLOT(setPhi(int)));
    Wnd->connect(QMGL, SIGNAL(phiChanged(int)), phi, SLOT(setValue(int)));
    phi->setToolTip(TR("Set value of \\phi angle."));
//  bb->addSeparator();
}
// zooming menu
{
    oo = o->addMenu(TR("Zoom/move"));
    bb = new QToolBar(TR("Zoom graphics"),Wnd);
    Wnd->addToolBar(Qt::LeftToolBarArea, bb);
    a = new QAction(QPixmap(":/usr/include/mathgl-2.1.2/include/xpm/left_1.xpm"), TR("Move &left"),  Wnd);
    Wnd->connect(a, SIGNAL(triggered()), QMGL, SLOT(shiftLeft()));
    a->setToolTip(TR("Move graphics left by 1/3 of its width."));
    bb->addAction(a);       oo->addAction(a);
    a = new QAction(QPixmap(":/usr/include/mathgl-2.1.2/include/xpm/up_1.xpm"), TR("Move &up"), Wnd);
    Wnd->connect(a, SIGNAL(triggered()), QMGL, SLOT(shiftUp()));
    a->setToolTip(TR("Move graphics up by 1/3 of its height."));
    bb->addAction(a);       oo->addAction(a);
    a = new QAction(QPixmap(":/usr/include/mathgl-2.1.2/include/xpm/zoom_1.xpm"), TR("Zoom &in"), Wnd);
    Wnd->connect(a, SIGNAL(triggered()), QMGL, SLOT(zoomIn()));
    a->setToolTip(TR("Zoom in graphics."));
    bb->addAction(a);       oo->addAction(a);
    a = new QAction(QPixmap(":/usr/include/mathgl-2.1.2/include/xpm/norm_1.xpm"), TR("Zoom &out"), Wnd);
    Wnd->connect(a, SIGNAL(triggered()), QMGL, SLOT(zoomOut()));
    a->setToolTip(TR("Zoom out graphics."));
    bb->addAction(a);       oo->addAction(a);
    a = new QAction(QPixmap(":/usr/include/mathgl-2.1.2/include/xpm/down_1.xpm"), TR("Move &down"), Wnd);
    Wnd->connect(a, SIGNAL(triggered()), QMGL, SLOT(shiftDown()));
    a->setToolTip(TR("Move graphics up down 1/3 of its height."));
    bb->addAction(a);       oo->addAction(a);
    a = new QAction(QPixmap(":/usr/include/mathgl-2.1.2/include/xpm/right_1.xpm"), TR("Move &right"), Wnd);
    Wnd->connect(a, SIGNAL(triggered()), QMGL, SLOT(shiftRight()));
    a->setToolTip(TR("Move graphics right by 1/3 of its width."));
    bb->addAction(a);       oo->addAction(a);
}
// animation menu
{

}

Wnd->menuBar()->addSeparator();

return popup;
}


plot::plot(QObject *parent) :
    QObject(parent)
{
}

plot::plot(QString FileToOpen)
{

//int For Number of Points in Parsed File
int NumberofPoints = 0;

//Set Name for emit signal
//FileName = FileNameOpen;

//Count Number of Points in File
{
    //Open the Selected File
    QFile FileOpen(FileToOpen);
    QTextStream InFile( &FileOpen);
    QString Line;

    //If File Not Open Then Stop
    if (!FileOpen.open(QIODevice::ReadOnly | QIODevice::Text))
        return;

    //Count Number of Points in File
    while (!InFile.atEnd())
        {
            Line  = InFile.readLine();
            NumberofPoints = NumberofPoints + 1;
         }
    FileOpen.flush();
    FileOpen.close();
}

//Set Data Size
arma::mat residuals;
residuals.set_size(NumberofPoints,3);

//Get Data
{
QFile FileOpen2(FileToOpen);
QTextStream InFile2( &FileOpen2);
QString Line2;

//If File Not Open Then Stop
if (!FileOpen2.open(QIODevice::ReadOnly | QIODevice::Text))
    return;

//Indices for Keeping Track
int index = 0;

//Get Data in Matrix
QStringList LineSplit;
QRegExp format("(\\ )");

while (!InFile2.atEnd())
    {
        Line2  = InFile2.readLine();
        index = index + 1;
        LineSplit = Line2.split(format,QString::SkipEmptyParts);
        residuals(index -1,0) = LineSplit.at(0).toDouble();
        residuals(index -1,1) = LineSplit.at(1).toDouble();
        residuals(index -1,2) = LineSplit.at(2).toDouble();
    }
FileOpen2.flush();
FileOpen2.close();
}

//Graph
mglGraph Plot3D;
Plot3D.SetSize(1680,1050);
Plot3D.SetFontSize(2);

//Containers
int nop = residuals.n_rows;
mglData x(nop);
mglData y(nop);
mglData z(nop);

//Place Data in Cotainers
for(int i = 0; i <= nop -1; i++)
    {
    x.a[i] = residuals(i,0);
    y.a[i] = residuals(i,1);
    z.a[i] = residuals(i,2);
    }

//Plot
//Range
arma::vec maxvalues; maxvalues.set_size(3);
arma::vec minvalues; minvalues.set_size(3);
maxvalues = (max(residuals).t());
minvalues = (min(residuals).t());

Plot3D.SetRange('x',minvalues[0],maxvalues[0]);
Plot3D.SetRange('y',minvalues[1],maxvalues[1]);
Plot3D.SetRange('z',minvalues[2],maxvalues[2]);
Plot3D.SetRange('c',minvalues[2],maxvalues[2]);

Plot3D.Light(true);  Plot3D.Rotate(50,10);
Plot3D.Axis();       Plot3D.Box();

Plot3D.Label('x',"\\i{cm}",1);
Plot3D.Label('y',"\\i{cm}",1);
Plot3D.Label('z',"\\i{cm}",1);

Plot3D.Colorbar();
Plot3D.Puts(mglPoint(360,68),"\\i{cm}");
Plot3D.Crust(x,y,z);

//Window to show Plot
QMainWindow *Wnd = new QMainWindow();
Wnd->resize(850,680);
Wnd->setWindowTitle("Title");
QScrollArea *scroll = new QScrollArea(Wnd);

//Setup QMathGL
QMathGL *QMGL = new QMathGL(Wnd);
QSpinBox *tet;
QSpinBox *phi;
QMenu *popup;

popup = mglMakeMenu(Wnd,QMGL, tet, phi);
QMGL->setGraph(&Plot3D);
QMGL->setPopup(popup);
QMGL->update();

  //window & menu
  scroll->setWidget(QMGL);
  Wnd->setCentralWidget(scroll);
  Wnd->show();

}

I used this QMenu to create the menu, which works great, but the buttons have no functionality yet. My question is, how and where would be the best way to implement the functionality of all the menu buttons?

Sorry for long post :)

Thanks in advance!

Was it helpful?

Solution

You will need something like the code provided below.

mainwindow.h

    // ...
 private slots:
     void newFile();
     void open();
     void save();
     void print();
     void undo();
     void redo();
     void cut();
     void copy();
     void paste();
     void about();
     void aboutQt();

 private:
     void createActions();
     void createMenus();

     QMenu *fileMenu;
     QMenu *editMenu;
     QMenu *formatMenu;
     QMenu *helpMenu;
     QAction *newAct;
     QAction *openAct;
     QAction *saveAct;
     QAction *printAct;
     QAction *exitAct;
     QAction *undoAct;
     QAction *redoAct;
     QAction *cutAct;
     QAction *copyAct;
     QAction *pasteAct;
     QAction *aboutAct;
     QAction *aboutQtAct;
     // ...

mainwindow.cpp

 void MainWindow::createActions()
 {
     newAct = new QAction(tr("&New"), this);
     newAct->setShortcuts(QKeySequence::New);
     newAct->setStatusTip(tr("Create a new file"));
     connect(newAct, SIGNAL(triggered()), this, SLOT(newFile()));

     openAct = new QAction(tr("&Open..."), this);
     openAct->setShortcuts(QKeySequence::Open);
     openAct->setStatusTip(tr("Open an existing file"));
     connect(openAct, SIGNAL(triggered()), this, SLOT(open()));

     saveAct = new QAction(tr("&Save"), this);
     saveAct->setShortcuts(QKeySequence::Save);
     saveAct->setStatusTip(tr("Save the document to disk"));
     connect(saveAct, SIGNAL(triggered()), this, SLOT(save()));

     printAct = new QAction(tr("&Print..."), this);
     printAct->setShortcuts(QKeySequence::Print);
     printAct->setStatusTip(tr("Print the document"));
     connect(printAct, SIGNAL(triggered()), this, SLOT(print()));

     exitAct = new QAction(tr("E&xit"), this);
     exitAct->setShortcuts(QKeySequence::Quit);
     exitAct->setStatusTip(tr("Exit the application"));
     connect(exitAct, SIGNAL(triggered()), this, SLOT(close()));

     undoAct = new QAction(tr("&Undo"), this);
     undoAct->setShortcuts(QKeySequence::Undo);
     undoAct->setStatusTip(tr("Undo the last operation"));
     connect(undoAct, SIGNAL(triggered()), this, SLOT(undo()));

     redoAct = new QAction(tr("&Redo"), this);
     redoAct->setShortcuts(QKeySequence::Redo);
     redoAct->setStatusTip(tr("Redo the last operation"));
     connect(redoAct, SIGNAL(triggered()), this, SLOT(redo()));

     cutAct = new QAction(tr("Cu&t"), this);
     cutAct->setShortcuts(QKeySequence::Cut);
     cutAct->setStatusTip(tr("Cut the current selection's contents to the "
                             "clipboard"));
     connect(cutAct, SIGNAL(triggered()), this, SLOT(cut()));

     copyAct = new QAction(tr("&Copy"), this);
     copyAct->setShortcuts(QKeySequence::Copy);
     copyAct->setStatusTip(tr("Copy the current selection's contents to the "
                              "clipboard"));
     connect(copyAct, SIGNAL(triggered()), this, SLOT(copy()));

     pasteAct = new QAction(tr("&Paste"), this);
     pasteAct->setShortcuts(QKeySequence::Paste);
     pasteAct->setStatusTip(tr("Paste the clipboard's contents into the current "
                               "selection"));
     connect(pasteAct, SIGNAL(triggered()), this, SLOT(paste()));

     aboutAct = new QAction(tr("&About"), this);
     aboutAct->setStatusTip(tr("Show the application's About box"));
     connect(aboutAct, SIGNAL(triggered()), this, SLOT(about()));
     // ...
}

 void MainWindow::createMenus()
 {
     fileMenu = menuBar()->addMenu(tr("&File"));
     fileMenu->addAction(newAct);
     fileMenu->addAction(openAct);
     fileMenu->addAction(saveAct);
     fileMenu->addAction(printAct);
     fileMenu->addSeparator();
     fileMenu->addAction(exitAct);

     editMenu = menuBar()->addMenu(tr("&Edit"));
     editMenu->addAction(undoAct);
     editMenu->addAction(redoAct);
     editMenu->addSeparator();
     editMenu->addAction(cutAct);
     editMenu->addAction(copyAct);
     editMenu->addAction(pasteAct);
     editMenu->addSeparator();

     helpMenu = menuBar()->addMenu(tr("&Help"));
     helpMenu->addAction(aboutAct);
     helpMenu->addAction(aboutQtAct);

    }

// ...

Please see the following QMenu example for details:

http://www.trinitydesktop.org/docs/qt4/mainwindows-menus.html

That all being said, you may wanna give a try to QML for new Qt based applications.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top