Method "setupUi" is not found in a window constructor.



  • I try to develop a small application with the help of the tool "Qt Creator 2.0.1" (revision 97d831e3de). It generated a skeleton which I adjusted a bit.

    Example.pro:
    @QT += core gui

    TARGET = Example
    TEMPLATE = app

    SOURCES += main.cpp
    mainwindow.cpp

    HEADERS += mainwindow.h

    FORMS += mainwindow.ui
    @

    mainwindow.h:
    @#ifndef MAIN_WINDOW_H
    #define MAIN_WINDOW_H

    #include <QMainWindow>

    namespace Ui {
    class MainWindow;
    }

    class MainWindow : public QMainWindow
    {
    Q_OBJECT

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

    #if 0
    private:
    #define USE_MAIN_WINDOW_POINTER 1
    QSharedPointerUi::MainWindow ui;
    #endif
    };

    #endif
    @

    mainwindow.cpp:
    @#include "mainwindow.h"
    #include "ui_mainwindow.h"

    MainWindow::MainWindow(QWidget* parent)
    #ifdef USE_MAIN_WINDOW_POINTER
    : QMainWindow(parent),
    ui(new Ui::MainWindow)
    {
    ui->setupUi(this);
    }
    #else
    : QMainWindow(parent)
    {
    setupUi(this);
    }
    #endif
    @

    main.cpp:
    @#include <QtGui/QApplication>
    #include <iostream>
    #include "mainwindow.h"

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

    return a.exec&#40;&#41;;
    }
    catch(...)
    {
    std::cerr << QT_TR_NOOP("An unknown exception was caught.") << std::endl;
    
    return EXIT_FAILURE;
    }
    

    }
    @

    I stumble on the following error message.
    'setupUi' was not declared in this scope

    Do I overlook any detail why this member function can not be called as I would expect it?



  • mainwindow.cpp:14

    setupUI() is a method of ui object.

    you should call
    @ui->setupUi();@



  • [quote author="danilocesar" date="1287605807"]
    setupUI() is a method of ui object.
    [/quote]

    The usage of this class attribute depends on the preprocessor symbol "USE_MAIN_WINDOW_POINTER" in my use case. I would like to avoid this extra pointer at the mentioned places in the source files.

    I hope that my design approach can also work without "call forwarding/redirection":http://en.wikipedia.org/wiki/Private_class_data_pattern.



  • setupUi() is a method of the ui class. So if you want to use it without the ui pointer you must inherit your widget from Ui::MainWindow too. You'll find that explained in Section "The Multiple Inheritance Approach":http://doc.trolltech.com/main-snapshot/designer-using-a-ui-file.html#the-multiple-inheritance-approach of the Qt Designer manual.



  • [quote author="Volker" date="1287611287"]So if you want to use it without the ui pointer you must inherit your widget from Ui::MainWindow too.[/quote]

    Does my class "MainWindow" belong to the name space "Ui"?

    Should the member function "setupUi" be inherited from the base class "QWidget" in both call paths?



  • MainWindow and Ui::MainWindow are DIFFERENT classes.



  • If you inherit from the UI class, your implementation class has access to the setupUI() method. QWidget does not provide any setupUI() method.

    Just follow the example in the link to the multiple inheritance example.

    To answer your first question: No, your class will not be in the Ui namespace.



  • My first question is: Why do you do this:
    @#ifdef USE_MAIN_WINDOW_POINTER
    : QMainWindow(parent),
    ui(new Ui::MainWindow)
    {
    ui->setupUi(this);
    }
    #else
    : QMainWindow(parent)
    {
    setupUi(this);
    }
    #endif@

    What benefits do you get? I think you pick one way and follow it. Otherwise you get headache.



  • [quote author="Volker" date="1287616637"]QWidget does not provide any setupUI() method.[/quote]

    I get other informations from the "documentation":http://doc.qt.nokia.com/4.7/qwidget.html#setupUi.



  • The note in the docs says it clearly:

    bq. from the docs:
    Sets up the user interface for the specified widget.
    Note: This function is available with widgets that derive from user interface descriptions created using uic.

    If you do not derive from the Ui::MainWindow class you do NOT have this function.

    But anyways - did you try it already? It really works in real programs, trust me ;-)



  • [quote]What benefits do you get?[/quote]

    I try to use an easier design approach for my use case.

    [quote]I think you pick one way and follow it.[/quote]

    I would like to call the member function "setupUi" directly (without an intermediate pointer).
    Unfortunately, I was surprised by the error message "‘setupUi’ was not declared in this scope".



  • bq. I would like to call the member function “setupUi” directly (without an intermediate pointer).
    Unfortunately, I was surprised by the error message ”‘setupUi’ was not declared in this scope”.

    That's easy. Inherit privately from Ui::MainWindow and you're done.



  • There are three ways of embedding your ui into your class:

    1. Private inheritance.
    2. Aggregation.
    3. Aggregation by pointer.

    The one of the above should be picked and used.

    Looking at your USE_MAIN_WINDOW_POINTER I start to think you are trying to mix those.

    As for ui header, then

    @#include "ui_mainwindow.h"@

    this should be in MainWindow.h.

    And I think you should remove this part:
    @namespace Ui {
    class MainWindow;
    }@



  • I would prefer inheritance for my use case here.

    [quote]Looking at your USE_MAIN_WINDOW_POINTER I start to think you are trying to mix those.[/quote]

    That's not my intention. I kept the flag to show that the "Pimpl design approach":http://en.wikipedia.org/wiki/Private_class_data_pattern#Also_known_as works as usual.

    I do also not get rid of the unexpected error message if I reduce the affected declaration to the following.
    mainwindow.h:
    @#ifndef MAIN_WINDOW_H
    #define MAIN_WINDOW_H
    #include <QMainWindow>

    class MainWindow : public QMainWindow
    {
    Q_OBJECT
    public:
    explicit MainWindow(QWidget* parent = 0);
    };
    #endif
    @



  • Of course you get the error message. You still do not inherit from your Ui::MainWindow GUI class.

    Just follow the example in the "docs":http://doc.trolltech.com/main-snapshot/designer-using-a-ui-file.html#the-multiple-inheritance-approach



  • [quote author="Volker" date="1287690429"]You still do not inherit from your Ui::MainWindow GUI class.[/quote]

    I have got the impression that the suggested inheritance is already applied if the pointer attribute is used in my example. The name space "Ui" contains just a "forward declaration":http://codepedia.com/1/CppForwardDeclaration as a recommendation from the Qt application template. (I can even try to omit this design detail.)



  • Of course you can omit the forward declaration. In case you inherit you must include the header file (ui_mainwindow.h in your case).

    You did read the section "The Multiple Inheritance Approach" in the link mentioned above, didn't you? The example there is exactly what you want. Just start from scratch (leaving out your #defines and #ifdefs), replace QWidget with QMainWindow and CalculatorForm with MainWindow and you're done.

    BTW: How do you manage to inherit from something, that you don't put into the inheritance list of your class declaration?



  • You are right. I have needed a bit more time to understand the involved dependencies in this Qt application context.

    I admit that all adjustment consequences were not completely clear for me so far while switching from a "Direct Approach" to a design approach with single or multiple inheritance.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.