Search code examples
c++qtuser-interfaceheader-filessignals-slots

QT/C++ yet another issue about accessing UI files


Although I have read the answers to this question

QT/C++ - Accessing MainWindow UI from a different class and searched the whole www for quite some time - I don't get it working.

I was given the task to recreate an applications UI using QT Designer. Unfortunately there was already some UI spread all over several classes (the team then came across the idea, that using QT but not using the Designer however "handcoding" the UI seems to make little sense)

So now my job is to untangle the open ends, create a GUI (done that) find every possible signal and slot and put it all together to look nice and clean.

So much for the theoretical part.

Addition: I have very little experience in C++ and I seem to be getting nowhere searching for answers and don't have the time to read whole books until tomorrow, otherwise I wouldn't ask.

I am kind of going nuts about two things:

A) My mainwindow.cpp, mainwindow.h and mainwindow.ui need to be linked into other files e.g. the previewwidget.cpp... the previewwidget.cpp had a lot of code like:

 buttonLayout->addWidget(fpsSpinBox, 0, Qt::AlignCenter);
 buttonLayout->addWidget(playButton, 0, Qt::AlignCenter);
 buttonLayout->addWidget(backwardButton, 0, Qt::AlignCenter);

apparently I replaced it by creating the corresponding buttons in Designer. now in the same file theres the connect SIGNAL SLOT entries (I added the "ui->")

 connect(ui->playButton, SIGNAL(clicked()), this, SIGNAL(playButtonClicked()));
 connect(ui->stopButton, SIGNAL(clicked()), this, SIGNAL(stopButtonClicked()));
 connect(ui->forwardButton, SIGNAL(clicked()), this, SIGNAL(forwardButtonClicked()));

but the compiler keeps telling me:

\preview\previewwidget.cpp:77: Error:'ui' was not declared in this scope

I put the ui_mainwindow.h into the header but that wasn't the solution either.


B) This Question is probably related very closely to the first one: since the Designer strickly keeps model/view/controll apart I need to rewrite the signals and slots to match the new UI - has anyone got a good tutorial or any hints for me how to do this fast and uncomplicated?

Any help would be greatly appreciated.


Solution

  • Let's assume you have a class called MyWidget and a corresponding ui file MyWidget.ui. In order to use it in your class I would do the following:

    • In the MyWidget.ui set a value to the objectName. It's the first property in the Property Editor if you open the file with the Designer. I would name it MyWidget

    • In the MyWidget.h you have to do the following:

      • Declare a namespace for the ui object and forward declare it.
      • Add as member variable (private) a pointer to the ui object.

    Sample header file follows:

    #ifndef MY_WIDGET_H_
    #define MY_WIDGET_H_
    
    #include <QWidget>
    
    namespace Ui {
        class MyWidget;
    }
    
    class MyWidget : public QWidget {
       Q_OBJECT
    public:
       MyWidget(QWidget* parent = NULL);
       ~MyWidget();
    
       // Add other class functions
    private:
       Ui::MyWidget ui;
    }   
    
    #endif // MY_WIDGET_H_
    
    • In the MyWidget.cpp
      • Include the automatically generated ui_MyWidget.h
      • Create a new ui object in the constructor
      • Call the setupUi function in the constructor
      • Delete the ui in the destructor

    Sample code:

    #include "MyWidget.h"
    #include "ui_MyWidget.h"
    
    MyWidget::MyWidget(QWidget *parent)
    :QWidget(parent), ui(new Ui::MyWidget)
    {
        ui->setupUi(this);
    }
    
    MyWidget::~MyWidget()
    {
        delete ui;
    }
    

    Now you are ready to use the ui throughout your class. For example if you have a spin box called spinBox1 you can take its value using

    int val = ui->spinBox1->value();
    

    .ui Signals and Slots

    I would advise you to use QtDesigner in order to make the connections between ui widgets and slots. Check this link for more details.

    If you want to connect a widget with a custom slot you can again do it using the designer.

    1. Switch to Edit Signals/Slots mode (F4)
    2. Drag and drop from the widget which it to emit the signal, to the widget which is to receive the signal.
    3. A Configure Connection dialog appears, showing the signals for the emitting widget, and the slots for the receiving widget. Click Edit... below the slots column on the right.
    4. A Signals/Slots of ReceivingWidget dialog appears. In here its is possible to click the plus icon beneath slots to add a new slot of any name.
    5. You can then go back and connect to your new slot in the Configure Connection dialog, or indeed in the Signal/Slot Editor dockwidget back in the main window.