0

I currently try to write an little application for experiments and more. I write everything in its own file (Menu -> menu.cpp etc.). Now I want to create a menu action, this works but interacting with the action doesnt. Thats what I've done so far:

menu.cpp

#include "menu.h"
#include <QMenuBar>
#include <QMenu>
#include <QAction>


void Menu::setupMenu(QMainWindow *window) {
    QMenuBar *mb = new QMenuBar();
    QMenu *fileMenu = new QMenu("File");
    QAction *newAct = new QAction("New...", window);
    window->connect(newAct, SIGNAL(triggered()), this, SLOT(newFile()));
    fileMenu->addAction(newAct);
    mb->addMenu(fileMenu);
    window->setMenuBar(mb);
}

void Menu::newFile() {
    printf("hello world!");
}

menu.h

#ifndef MENU_H
#define MENU_H

#include <QObject>
#include <QMainWindow>
#include <QWidget>
#include <QMenuBar>

class Menu : public QObject
{
public:
    void setupMenu(QMainWindow *window);
private slots:
    void newFile();
};

#endif // MENU_H

But its not printing out 'hello world', the only message I get is:

QObject::connect: No such slot QObject::newFile() in ../from Scratch written UI app C++/src/ui/menu.cpp:11

What can I do to fix this?

~ Jan

Jan
  • 111
  • 1
  • 2
  • 4

1 Answers1

0

class Menu : public QObject

Menu is a QObject but is also needs to use the Q_OBJECT macro.

See the Qt5 - QObject documentation:

The Q_OBJECT macro must appear in the private section of a class definition that declares its own signals and slots or that uses other services provided by Qt's meta-object system.

Next, there is some confusion in your connect call. Here is the signature of the static connect function.

Qt5 - static QObject::connect:

QObject::connect(const QObject * sender, const char * signal, const QObject * receiver, const char * method, Qt::ConnectionType type = Qt::AutoConnection)

You can see it takes 5 parameters (object pointer, signal, object pointer, signal/slot) and the 5th parameter is defaulted.

There is also a member function connect.

Qt5 - QObject::connect:

QObject::connect(const QObject * sender, const char * signal, const char * method, Qt::ConnectionType type = Qt::AutoConnection) const

This takes 4 parameters (object pointer, signal, signal/slot) and the 4th parameter is defaulted.

Your code:

window->connect(newAct, SIGNAL(triggered()), this, SLOT(newFile()));

You're calling the the connect member function of window but you're passing parameters for the static connect function.

What can I do to fix this?

Figure out what you're trying to do and make the appropriate call.

For example: connect the QAction signal to a slot in Menu then either call the static function as follows.

connect(newAct, SIGNAL(triggered()), this, SLOT(newFile()));

Or using the member function.

connect(newAct, SIGNAL(triggered()), SLOT(newFile()));
James Adkison
  • 9,412
  • 2
  • 29
  • 43
  • When I add **Q_OBJECT** into the header file I get th error that there is an **`undefined reference to vtable for Menu`**. – Jan Apr 25 '15 at 15:50
  • 1
    You need to moc the object properly and compile/link the output it generates. You should be able to easily find questions/answers about this (e.g., [Q_OBJECT throwing 'undefined reference to vtable' error](http://stackoverflow.com/questions/4774291/q-object-throwing-undefined-reference-to-vtable-error), [Qt Object Linker Problem “ undefined reverence to vtable”](http://stackoverflow.com/questions/2555816/qt-object-linker-problem-undefined-reverence-to-vtable)). – James Adkison Apr 25 '15 at 15:54
  • Removed the .user-file now it works! Thanks for this! – Jan Apr 25 '15 at 16:02