PDA

View Full Version : Compiler error when connecting a QAction of a menu bar



jcbaraza
17th June 2012, 03:35
Hi everyone,

I'm migrating an old (well, really ancient) Windows application from Borland Builder 3 to Qt. I've started creating a new project, particularly a Qt Gui application. I've used as an example the editabletreemodel project included in the demos. Hence, the project includes simply a form (that I've renamed as VFIT_W) and a main file. Well, first of all I've created a menu bar (with no operative options; just to see the menu options) and (reading help everywhere) a status bar. While I designed this useless form, I've been able to compile and run the application.

The problem has appeared when I've tried to activate the first option of the menu bar: Exit. I've written a simple function called ExitClick, and connected this function to Exit QAction. However, a compiler error appears. Can anyone tell me where's the mistake, please?

The form code looks like this. This are the elements in the main window (basically the menu bar, as the status bar has been generated in the constructor):

7864

This is the header of the main window (VFIT_W.h file):


#ifndef VFIT_W_H
#define VFIT_W_H

#include <QMainWindow>
#include <QLabel>

namespace Ui {
class VFITW;
}

class VFITW : public QMainWindow
{
Q_OBJECT

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

private:
Ui::VFITW *ui;
QLabel *st_1, *st_2, *st_3;

private slots:
void ExitClick();
};

#endif // VFIT_W_H

This is the code of the main window (VFIT_W.cpp file):


#include <QtGui>
#include <QWidget>
#include <QAction>

#include "VFIT_W.h"
#include "ui_VFIT_W.h"

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

// Show main window maximized
this->setWindowState(Qt::WindowMaximized);

// Create status bar
st_1 = new QLabel("Left", this);
st_1->setMinimumSize(150, 20);
st_1->setMaximumSize(500, 20);
st_1->setFrameStyle(QFrame::Panel | QFrame::Sunken);
st_1->setAlignment(Qt::AlignCenter | Qt::AlignRight);
st_1->setWhatsThis("Info left");
st_2 = new QLabel("Middle", this);
st_2->setMinimumSize(450, 20);
st_2->setFrameStyle(QFrame::Panel | QFrame::Sunken);
st_2->setAlignment(Qt::AlignCenter | Qt::AlignRight);
st_2->setWhatsThis("Info middle");
st_3 = new QLabel("Right", this);
st_3->setMinimumSize(700, 20);
st_3->setFrameStyle(QFrame::Panel | QFrame::Sunken);
st_3->setAlignment(Qt::AlignCenter | Qt::AlignRight);
st_3->setWhatsThis("Info right");

statusBar()->addPermanentWidget(st_1, 0);
statusBar()->addPermanentWidget(st_2, 0);
statusBar()->addPermanentWidget(st_3, 100);

connect(Exit, SIGNAL(triggered()), qApp, SLOT(ExitClick()));

}

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

void VFITW::ExitClick()
{
exit(EXIT_SUCCESS);
}

The error (error: 'Exit' was not declared in this scope) refers to the "connect" code line. In the editabletreemodel project that I've used as a model, the connection of the "exit" option of the main menu is made exactly the same (although the names of both the QAction and the function are different).

On the other hand, I've kept the code related to the creation of the status bar because I also have a small problem with the "WhatsThis" messages in the status bar: they don't appear. I haven't seen anywhere if I need to activate or configure this property so I don't understand why they don't become visible.

Finally, this is the code of the main.cpp file:


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

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

return a.exec();
}


There are many differences from Builder 3, and I don't understand much of the automatic code generated (like "#include "ui_VFIT_W.h" " in the VFITW.cpp file...), but I hope to end up to manage. I wish there was an application which would "translate" code from Builder 3 to Qt! ;) . Meanwhile, I'll have to do my best on my own or with some help...

Thanks a lot!

wysota
17th June 2012, 11:59
Should be ui->Exit, most probably, since everything you did in Designer is part of the ui object.

jcbaraza
17th June 2012, 14:40
Thank you so much! It worked, although I've also had to change "qApp" to "this" in the connect sentence (connect(ui->Exit, SIGNAL(triggered()), qApp, SLOT(ExitClick()));). What I don't understand is why I have to use ui-> to refer to "Exit" QAction, but not to refer to "statusBar" status bar. By the way, do you know why the hints (the "WhatsThis" messages) in the status bar don't appear?

Thanks again.

wysota
17th June 2012, 14:57
What I don't understand is why I have to use ui-> to refer to "Exit" QAction, but not to refer to "statusBar" status bar.
That's because ui->Exit is a member of the UI::Something class and statusBar() is really QMainWindow::statusBar() which is a method returning an object pointer in the QMainWindow class.

I suggest you get a good book on object oriented programing and read it. Then things like that will become clear.


By the way, do you know why the hints (the "WhatsThis" messages) in the status bar don't appear?
They are not meant to appear there.

jcbaraza
19th June 2012, 02:36
Thank you so much again! The problem lies on the big differences with Builder. There, both the main menu and the the status bar are children objects from the MainForm class. So this new philosophy put me offside.

Regarding my trouble with trouble with hints, after reviewing my original code in Builder (made twelve years ago), I've realized that it wasn't as easy as I remembered. In that code, I needed to know which pannel (the equivalent in Builder to Qt's widgets) was under the mouse, and then modify the "Hint" property (equivalent to Qt's "toolTip") and then show it. So I think I'll have to do just the same: to use the mouse or status bar events to guess what (i.e., which widget) is under the mouse, and then to proceed.

Another possibility that I've thought is to add another object different from QLabels as widgets in the status bar (such as QWidgets containing the QLabels), and associate the desired toolTip to each QWidget. Please remember my original code on lines 17 to 37 of VFITW.cpp code, included in my first post. The resulting status bar is like tis:

7866

The final result should be that when moving the mouse on the status bar, three different messages should appear depending on the particular status bar "field" overflied, just like this:

7867 7868 7869

Thanks again. I'll tell how I managed with both options, or with any other that I could try :confused:.

ChrisW67
19th June 2012, 06:21
Just set the tool tip property of each widget (QWidget::setToolTip()) you add to the status bar and Qt will handle them for you.

jcbaraza
19th June 2012, 19:54
Great! It worked, and it was much easier than I thought. I only needed to type correctly "setToolTip" (instead of "setWhatsThis" in my first try) in the declaration of the hints:


st_1->setToolTip("Info left");
...
st_2->setToolTip("Info middle");
...
st_3->setToolTip("Info right");

Thanks!