CopperSpice API  1.7.4
Loading a UI File

A UI file is a human readable XML document. The elements in the file contain a description of the widgets and controls for a particular form which is then used to create a graphical user interface window or dialog. The UI files are used at compile time to generate source code, which is then linked with your application.

Using UI Files

Although you can create a UI file by hand this approach is not recommended since it is error prone and tedious. The preferred approach is to use the CS Designer application to create your UI files.

UI file when building your application. In the process of compiling your program the UIC program will parse each UI file and generate a corresponding header file containing a C++ class. This class contains the following data members and methods.

  • One data member declaration for each widget, control, layout, button group, action, etc
  • Initialization method called setupUi() which constructs all of the data members
  • A class method called retranslateUi() which handles translations for any text on the form

The generated header is used in your application in one of the following ways.

Direct Approach

To use the direct approach include the "ui_calculatorform.h" header in main.cpp. The first step is to create a QWidget and then construct the calculator UI by calling the generated setupUI() method. This will setup the user interface and any signal and slot connections which were defined in the UI file.

The direct approach provides a quick and easy way to use a UI in your application for simple user interfaces. If your UI requires a custom slot method or more complicated connections, then the single inheritance approach will be required.

#include "ui_calculatorform.h"
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
QWidget *widget = new QWidget;
Ui::CalculatorForm m_ui;
m_ui.setupUi(widget);
widget->show();
return app.exec();
}

Single Inheritance Approach

To use the single inheritance approach create a new class which inherits from the top level widget. In this example we inherit from QWidget. If the UI form had been designed on a QMainWindow or a QDialog, then the corresponding classes should be used as the base class.

There are two ways to implement the single inheritance approach. The first way involves declaring a data member of type "Ui::CalculatorForm". The second way is to declare a data member which is a pointer to type "Ui::CalculatorForm".

Inheritance, Approach One

The constructor of the My_CalculatorForm class is responsible for calling the m_ui.setupUi() method which will instantiate all of the widgets and controls required to display the user interface.

The private "m_ui" variable can be used to access the elements of the user interface. The first parameter in the call to connect() is the Sender and in this example it will be either m_ui.spinBox1 or m_ui.spinBox2.

//** file name my_calculatorform.h
#include "ui_calculatorform.h"
#include <QWidget>
class My_CalculatorForm : public QWidget
{
CS_OBJECT(My_CalculatorForm)
public:
My_CalculatorForm(QWidget *parent = nullptr);
private:
// slot methods
void spinBox1_valueChanged(int value);
void spinBox2_valueChanged(int value);
Ui::CalculatorForm m_ui;
};

The corresponding source file is shown below.

//** file name my_calculatorform.cpp
My_CalculatorForm::My_CalculatorForm(QWidget *parent)
: QWidget(parent)
{
m_ui.setupUi(this);
connect( m_ui.spinBox1, &QSpinBox::valueChanged, this, &My_CalculatorForm::spinBox1_valueChanged );
connect( m_ui.spinBox2, &QSpinBox::valueChanged, this, &My_CalculatorForm::spinBox2_valueChanged );
}
My_CalculatorForm::spinBox1_valueChanged(int value)
{
// slot method which can do something
}
My_CalculatorForm::spinBox2_valueChanged(int value)
{
// slot method which can do something
}

Inheritance, Approach Two

The other way this code can be written is to declare the private "m_ui" variable as a pointer to the Ui::CalculatorForm. Using a pointer for m_ui means you will need to implement a destructor method.

One advantage of this second approach is the "class CalculatorForm" could be forward declared in the UI namespace, in my_calculatorform.h. In this case both "ui_calculatorform.h" and "my_calculatorform.h" need to be included in the cpp file.

// file name my_calculatorform.h
class "ui_calculatorform.h"
class My_CalculatorForm : public QWidget
{
CS_OBJECT(My_CalculatorForm)
public:
My_CalculatorForm(QWidget *parent = nullptr);
~My_CalculatorForm();
private :
// slot methods
void inputSpinBox1_valueChanged(int value);
void inputSpinBox2_valueChanged(int value);
Ui::CalculatorForm *m_ui;
};

The corresponding source file is shown below.

// file name my_calculatorform.cpp
#include "my_calculatorform.h"
My_CalculatorForm::CalculatorForm(QWidget *parent)
: QWidget(parent), m_ui(new Ui::CalculatorForm)
{
m_ui->setupUi(this);
connect( m_ui->spinBox1, &QSpinBox::valueChanged, this, &My_CalculatorForm::spinBox1_valueChanged );
connect( m_ui->spinBox2, &QSpinBox::valueChanged, this, &My_CalculatorForm::spinBox2_valueChanged );
}
My_CalculatorForm::~My_CalculatorForm()
{
delete m_ui;
}
My_CalculatorForm::spinBox1_valueChanged(int value)
{
// slot method which can do something
}
My_CalculatorForm::spinBox2_valueChanged(int value)
{
// slot method which can do something
}