0

I have a basic window that has a slot fileNew(). When I run my app, I get the following error:

QObject::connect: No such slot QMainWindow::fileNew()

Why is it not finding the slot?

SdiWindow.h

class SdiWindow : public QMainWindow
{
public:
  SdiWindow(QWidget * parent = 0);

private slots:
  void fileNew();

private:
  QTextEdit * docWidget;
  QAction * newAction;

  void createActions();
  void createMenus();
};

SdiWindow.cpp

SdiWindow::SdiWindow(QWidget * parent) : QMainWindow(parent)
{
  setAttribute(Qt::WA_DeleteOnClose);
  setWindowTitle( QString("%1[*] - %2").arg("unnamed").arg("SDI") );

  docWidget = new QTextEdit(this);
  setCentralWidget(docWidget);

  connect(
    docWidget->document(), SIGNAL(modificationChanged(bool)),
    this, SLOT(setWindowModified(bool))
  );

  createActions();
  createMenus();
  statusBar()->showMessage("Done");
}

void SdiWindow::createActions()
{
  newAction = new QAction( QIcon(":/images/new.png"), tr("&New"), this );
  newAction->setShortcut( tr("Ctrl+N") );
  newAction->setStatusTip( tr("Create a new document") );
  connect(newAction, SIGNAL(triggered()), this, SLOT(fileNew()));
}

void SdiWindow::createMenus()
{
  QMenu * menu = menuBar()->addMenu( tr("&File") );
  menu->addAction(newAction);
}

void SdiWindow::fileNew()
{
  (new SdiWindow())->show();
}

1 Answers1

2

SdiWindow needs to have the Q_OBJECT macro as its first line.

class SdiWindow : public QMainWindow
{
Q_OBJECT
public: ....

you will also have to use moc on the header file. The moc tool generates all the required C++ code for the signal and slot framework.

The generated moc code must be compiled and known to the linker. I do this by including the generated file in my implementation file like this

#include SdiWindow.h
#include SdiWindow.moc

drescherjm also suggests just compiling it on its own.

EDIT: In this case you're inheriting from QMainWindow, for future reference your class will need to inherit from QObject in some way to be able to use the signal/slot framework.

Boumbles
  • 2,473
  • 3
  • 24
  • 42
  • 2
    The including of the .moc is not necessarily needed. For me I have moc_classname.cxx. And these are sources of the project. – drescherjm Jun 13 '14 at 19:51
  • @drescherjm I've run into issues when I've not included it. Although it's possible that I've only forgotten to do so when calling things generated by moc... – Boumbles Jun 13 '14 at 19:52
  • @drescherjm I just tried commenting it out and I get linker errors. I believe that your moc code just needs to be compiled so it can be linked against. Whether this be in your implementation file or separately. – Boumbles Jun 13 '14 at 19:56
  • 1
    I was trying to point out that your method is not the only way. There are several ways that work depending on how moc is called. – drescherjm Jun 13 '14 at 19:58