Translate UI file to .cpp and .h files



  • Hi there !

    I created a UI file with Qt Designer and I would like to translate the ui file in .cpp and .h file.

    I know that a .h file is generated at the compilation but I really want to translate it. I tried to copy paste some code of the .h file but it doesn't really work...

    And I think it's better to create my own interface with code than with QtDesigner (you really know what you are doing...) and with a bit of reflection, it might be more easiest to have access to some object in the interface... (like QAction, QLineEdit, QCheckBox, etc.)

    I hope my explanations are not bad...

    So, to resume I would like to know how can I cut my .ui file to .cpp and .h file !!

    Somebody can help me ?



  • Hi
    Your question is to much generic for a specific answer. Every component such as buttons, edit boxes, layouts are perfectly doable in code, you just have to learn how to do it. By opening the ui file as text, you will see the generated code, you can copy it to a new class file and make the necessary changes, perhapes this is the best way.



  • you can write all initialization manually.
    Did you read
    C++ GUI.Programming.with.Qt.4 by Jasmin Blanchette, Mark Summerfield
    or
    The.Art.of.Building.Qt.Applications by Daniel Molkentin

    There are all information which you need.

    or you can get converted code from ui_xxx.h file from build folder.



  • Thanks (again) qxoz for those books, I'll read them to perform my user interface and to code manually !

    For the moment, I'll convert the generated code from the build folder !


  • Moderators

    Why would you want to copy the generated code into your project? The ui-files are so much nicer to update and everything!

    You can access all the objects that are created in the generated header file just fine (provided you give good names in the designer) and can do all the parts that need extra intelligence in your own code without copying all the boilerplate code.



  • Because I can't change values of some objects... my interface is like this picture (added with the post just for 48 hours ...)

    Click here to see picture:http://www.hiboox.fr/go/images/informatique/1-interface-selection-config,e8d3fa92545554baae7cf57a20a701fe.bmp.html

    and if a channel is selected (or more) in relation of labels, QLineEdit shall display channels selected and label selected...



  • ok ...

    For the first question it's easy, use 'uic.exe your_interface.ui' and pip the result to a file, after you could copy like you want.

    BUT ...

    It's not true to think that it's the best way, you do like this an hardcoding of your interface and any improvement will need lot of effort. But you don't inherit or delegate the generate .h to you class? You have access to all and don't need to copy paste anything.

    Now you are saying that you couldn't access to all you widgets, it's too not true, you could access and set any widget values! For the selection problem you have to connect to the toggled() signal of the checkbox to do a for (all labels - probably QLineEdit objects) (*it)->selectAll();

    And a small remark, I see an add label, which means you plan to add line, perhaps a QTable will be necessary!



  • I do not quite understand you
    You want to display different groups of controls for different modes?


  • Moderators

    Do use ui-files, put plain qwidgets with some layout wherever you need dynamic contents and then just add the custom widgets into those layouts. That minimizes the hardcoding you need to do.



  • [quote author="Tobias Hunger" date="1322154472"]Do use ui-files, put plain qwidgets with some layout wherever you need dynamic contents and then just add the custom widgets into those layouts. That minimizes the hardcoding you need to do.[/quote]

    Yes that is most right solution.
    I would like to offer the same thing.



  • [quote author="Tobias Hunger" date="1322154472"]Do use ui-files, put plain qwidgets with some layout wherever you need dynamic contents and then just add the custom widgets into those layouts. That minimizes the hardcoding you need to do.[/quote]

    That's exactly what I do regularly, it works like a charm.

    Regarding your UI: You could consider using an item view and a custom model for your table.



  • Thanks for all of your answers and I'm sorry to give you a later answer ... (This weekend I was in a business trip and I couldn't see your answers)

    So during this trip, I do the translation (it works very well ^^), I agree with you (Tobias) when you talk about reducing hardcoding when using .ui file :

    bq. That minimizes the hardcoding you need to do

    But to access to all my widgets, I will have too much functions like :

    @on_rxCh0_ComboBox_toggled(bool toggle)
    on_rxCh1_ComboBox_toggled(bool toggle)
    on_rxCh2_ComboBox_toggled(bool toggle)
    on_rxCh3_ComboBox_toggled(bool toggle)@

    etc. (if I'm using the .ui file)

    But my wish is (for example) :

    @if Add_Label is clicked // Pushbutton
    {
    if ((rxCh1 and rxCh2 is toggled) and (Label #022 is selected)) then
    rxChannelEdit1 = "Channel 1" //1st QLineEdit of Channel column
    rxChannelEdit2 = "Channel 2" //2nd QLineEdit of Channel column
    (rxLabelEdit1 and rxLabelEdit2) = "Label #022" //1st and 2nd QLineEdit of Label column
    }@
    this is one of the differents possibilities I want to realize...

    These explanations are more clear ?



  • Just to give you my big problem (for the moment), I want to modify a QLineEdit (as explain forward) so that's the function I wrote :

    in mainwindow.h :
    @private slots:
    bool on_rxCh0_CheckBox_toggled(bool checked);
    bool on_rxCh1_CheckBox_toggled(bool checked);
    bool on_rxCh2_CheckBox_toggled(bool checked);
    bool on_rxCh3_CheckBox_toggled(bool checked);

    public:
    void set_rxChannel_Edit1(QLineEdit *rx_Channel_edit);
    void set_rxChannel_Edit2(QLineEdit *rx_Channel_edit);
    void set_rxChannel_Edit3(QLineEdit *rx_Channel_edit);
    void set_rxChannel_Edit4(QLineEdit *rx_Channel_edit);

    private:
    QLineEdit *rx_Channel_1;
    QLineEdit *rx_Channel_2;
    QLineEdit *rx_Channel_3;
    QLineEdit *rx_Channel_4;@

    in mainwindow.cpp :
    @void MainWindow::set_rxChannel_Edit1(QLineEdit *rx_Channel_edit)
    {
    Ui_MainWindow::rx_Channel_edit_1 = rx_Channel_edit;
    }

    void MainWindow::set_rxChannel_Edit2(QLineEdit *rx_Channel_edit)
    {
    Ui_MainWindow::rx_Channel_edit_2 = rx_Channel_edit;
    }

    void MainWindow::set_rxChannel_Edit3(QLineEdit *rx_Channel_edit)
    {
    Ui_MainWindow::rx_Channel_edit_3 = rx_Channel_edit;
    }

    void MainWindow::set_rxChannel_Edit4(QLineEdit *rx_Channel_edit)
    {
    Ui_MainWindow::rx_Channel_edit_4 = rx_Channel_edit;
    }

    [...]

    void MainWindow::on_rxAddLabelButton_clicked()
    {
    rx_Channel_1 = new QLineEdit;
    rx_Channel_2 = new QLineEdit;
    rx_Channel_3 = new QLineEdit;
    rx_Channel_4 = new QLineEdit;

    if(ch0Checked){
        if(ch1Checked){
            if(ch2Checked){
                if(ch3Checked){
                    set_rxChannel_Edit1(rx_Channel_1->setText(tr("#0")));
                    set_rxChannel_Edit2(rx_Channel_2->setText(tr("#1")));
                    set_rxChannel_Edit3(rx_Channel_3->setText(tr("#2")));
                    set_rxChannel_Edit4(rx_Channel_4->setText(tr("#3")));
                }
                else{
                    set_rxChannel_Edit1(rx_Channel_1->setText(tr("#0")));
                    set_rxChannel_Edit2(rx_Channel_2->setText(tr("#1")));
                    set_rxChannel_Edit3(rx_Channel_3->setText(tr("#2")));
                }
            }
            else{
                set_rxChannel_Edit1(rx_Channel_1->setText(tr("#0")));
                set_rxChannel_Edit2(rx_Channel_2->setText(tr("#1")));
            }
        }
        else{
            set_rxChannel_Edit1(rx_Channel_1->setText(tr("#0")));
        }
    }
    

    }

    bool MainWindow::on_rxCh0_CheckBox_toggled(bool checked)
    {
    return ch0Checked;
    }

    bool MainWindow::on_rxCh1_CheckBox_toggled(bool checked)
    {
    return ch1Checked;
    }

    bool MainWindow::on_rxCh2_CheckBox_toggled(bool checked)
    {
    return ch2Checked;
    }

    bool MainWindow::on_rxCh3_CheckBox_toggled(bool checked)
    {
    return ch3Checked;
    }@

    And the error generate is :

    @.\API_A429-build-desktop-Qt_4_7_4_for_Desktop_-MinGW_4_4__Qt_SDK__Debug\ui_mainwindow.h:-1: In member function 'void MainWindow::set_rxChannel_Edit1(QLineEdit*)':
    .\API_A429-build-desktop-Qt_4_7_4_for_Desktop
    -MinGW_4_4__Qt_SDK__Debug\ui_mainwindow.h:87: erreur : object missing in reference to 'Ui_MainWindow::rx_Channel_edit_1'
    .\API_A429-build-desktop-Qt_4_7_4_for_Desktop
    -_MinGW_4_4__Qt_SDK__Debug..\API_A429\mainwindow.cpp:57: erreur : from this location@

    this same error for the 4 functions set_rxChannel_Edit x so that's why I think I can't get access to my widgets... (cause I'm using .ui file ...)

    I tried to found some answers about those errors but I don't...

    PS: I think the way I coded those actions is ... a bit barbarian ...



  • Hello lowee,

    You could solve your problem connecting your checkboxes into a unique SLOT by using "QSignalMapper":http://doc.qt.nokia.com/4.6/qsignalmapper.html.

    In the follow example I've created 4 checkboxes and 4 labels in Qt Designer. The name of objects is a prefix (QCheckbox = "cb" and QLabel = "lb") with a index number, working as suffix.

    mainwindow.h
    @#ifndef MAINWINDOW_H
    #define MAINWINDOW_H

    #include <QMainWindow>
    #include <QCheckBox>
    #include <QLabel>
    #include <QHash>
    #include <QSignalMapper>

    namespace Ui {
    class MainWindow;
    }

    class MainWindow : public QMainWindow
    {
    Q_OBJECT

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

    private slots:
    void onStateChange (const QString& checkboxName);

    private:
    QHash<QString,QString> labelList;
    Ui::MainWindow ui;
    QSignalMapper
    signalMapper;
    };

    #endif // MAINWINDOW_H
    @

    mainwindow.cpp
    @#include "mainwindow.h"
    #include "ui_mainwindow.h"
    #include <QDebug>

    #define CHECKBOX_PREFIX "cb"
    #define LABEL_PREFIX "lb"
    #define NUMBER_OF_CHECKBOXES 4

    MainWindow::MainWindow(QWidget parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow),
    signalMapper (new QSignalMapper(this))
    {
    ui->setupUi(this);
    char indexName[33];
    QString checkboxName;
    QString labelName;
    QCheckBox
    checkbox;
    QLabel* label;

    for (int i = 0; i < NUMBER_OF_CHECKBOXES; ++i) {
        itoa(i,indexName,10);
        checkboxName.append(CHECKBOX_PREFIX).append(indexName);
        labelName.append(LABEL_PREFIX).append(indexName);
    
        if ((checkbox = ui->centralWidget->findChild<QCheckBox* >(checkboxName)) && (label = ui->centralWidget->findChild<QLabel* >(labelName))){
            //for label update
            labelList[checkbox->objectName()] = labelName;
    
            //connect for further mapping
            connect(checkbox, SIGNAL(stateChanged(int)), signalMapper, SLOT(map()));
            signalMapper->setMapping(checkbox, checkboxName);
            }
    
        labelName.clear();
        checkboxName.clear();
    }
    
    connect(signalMapper, SIGNAL(mapped(const QString& )),
                 this, SLOT(onStateChange(const QString& )));
    

    }

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

    void MainWindow::onStateChange (const QString& checkboxName)
    {
    QLabel* label;

    if (label = ui->centralWidget->findChild<QLabel* >(labelList[checkboxName])){
        QCheckBox* checkbox =  ui->centralWidget->findChild<QCheckBox* >(checkboxName);
    
        switch (checkbox->checkState()){
        case  Qt::Checked :
            label->setText(tr("checked"));
            break;
    
        case  Qt::Unchecked :
            label->setText(tr("unchecked"));
            break;
    
        case  Qt::PartiallyChecked :
            label->setText(tr("PartiallyChecked"));
            break;
    
        default :
        break;
    
        }
    }
    

    }
    @

    Any doubt, feel free to ask :)



  • I think I understood (globally) ... I just don't understand those lines code but mostly the "if" condition

    @if ((checkbox = ui->centralWidget->findChild<QCheckBox* >(checkboxName)) && (label = ui->centralWidget->findChild<QLabel* >(labelName))){
    //for label update
    labelList[checkbox->objectName()] = labelName;

            //connect for further mapping
            connect(checkbox, SIGNAL(stateChanged(int)), signalMapper, SLOT(map()));
            signalMapper->setMapping(checkbox, checkboxName);
            }
    
        labelName.clear(); //here is just to reset the append() function ?
        checkboxName.clear(); // idem ?@
    

    Your function @onStateChange(const QString& checkboxName)@ is just if checkbox is set to triState ? And can you explain your condition @if (label = ui->centralWidget->findChild<QLabel* >(labelList[checkboxName])){@ and your instruction (following the condition) @QCheckBox* checkbox = ui->centralWidget->findChild<QCheckBox* >(checkboxName);@

    Thanks, anyway, for your help !



  • This onState SLOT, in this example, receives the SIGNAL emitted from checkbox, but could be connected to another SIGNAL if want to. The secret is that, through this first connect, I receive the SIGNAL from the object and, in the other one, I receive the object name.

    @
    onStateChange(const QString& checkboxName)
    @

    With the name of object, first, I verify if the related QLabel still exists.
    @
    if (label = ui->centralWidget->findChild<QLabel* >(labelList[checkboxName]))
    @

    If the object exists, I create a QCheckBox object, with the findChild method to get the current state.
    @QCheckBox* checkbox = ui->centralWidget->findChild<QCheckBox* >(checkboxName);@

    Finally, with these two objects I'm able to make the change in the related object.



  • Another solution could be extend the QLabel class and create a SLOT to receive the stateChanged from QCheckBox.

    The connection between them could be performed with the loop located in the class constructor.


Log in to reply
 

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