Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

[SOLVED]setupUi and using parent of an object



  • Hi everybody;
    Im rather new to Qt.I have 2 problems and 2 related questions.Here are they :

    1. I created a Qt gui project,which includes a form. (I may remove form but i want to use it). I hand-code some controls,which include layout.Since I have a MainWindow (derived from QMainWindow) i have to use another widget (right?) on top of MainWindow for layout purposes.Up to here no problem.Now if I try this code

    @ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent),
    ui(new Ui::MainWindow)
    {
    QWidget *central=new QWidget;
    this->setCentralWidget(central);
    ui->setupUi(central);
    .... @

    I have this error : mainwindow.cpp:15: error: invalid conversion from 'QWidget*' to 'QMainWindow*'

    Or, if I use this code

    @ MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
    {
    QWidget *central=new QWidget;
    this->setCentralWidget(central);
    ui->setupUi(this);
    ....... @

    program compiles and crashes at run-time.
    My question is : How to solve this problem?Isnt it possible to use qtdesigner in cooepration with hand-coded controls and layout?

    2)I have a MainWindow class derived from QMainWindow.I create one of this in main() function and use it as the main window of the application.
    And i have a MyLabel class derived from QLabel which I use in MainWindow.And I pass MainWindow instance as parent to MyLabel constructor.
    Now,in a member function of MyLabel I try to reach statusBar of MainWindow,which is now the parent.If Im not making a stupid error , I suppose that a code like this will work:

    @ parent->statusBar()->showMessage("hello qt"); @

    Errors : invalid use of member (did you forget the '&' ?)
    error: base operand of '->' is not a pointer
    What is wrongI thought I could emit a signal and consume it by mainwindow to update the statusbar.But is it possible to do this without emitting a signal,and using the parent?By the way, any other approach is appreciated.

    Thanks



  • Hi!

    For your first problem.
    First setupUi. Then add widgets and modify everything related to GUI.

    @ MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)

    {
    QWidget *central=new QWidget; // It's OK to consturct and initialize other variables before setting up the ui
    ui->setupUi(this); // Before setting central widget
    this->setCentralWidget(central);
    @

    And for your second problem, if I remember correctly, unless it's in a constructor, parent is a method, so you need to do:
    @ parent()->statusBar()->showMessage("hello qt"); // Notice: "parent()"->@

    And if you want to use it as a QMainWindow, you just cast it:
    @ ((QMainWindow *)parent())->statusBar()->showMessage("hello qt");@

    Regards,
    Jake



  • Hi Jake,thanks for the quick reply,

    I have further questions upon your clarifications,

    For Q1 ) According to your code,we setup the ui "upon" this (which is a MainWindow instance) right?So what is the relation of central with ui ? Shall I create new widgets with parent as "this" or "central" ? For instance,if I add layout (assume that i didnt add layout in designer and want to add in code) shall I create it with parent = this or parent = central?Plus,whose setLayout method shall I call?

    For Q2 ) Im not home right now,I will try both methods you proposed.



  • Central is on of the widgets shown in main window. If you create new widgets and you'll add them to main window, pass main window ( this in your case).

    And for setLayout(), it depends what you want. You probably want to call it on main window ( this). If you want widgets added to layout to be shown only in particular widget, you then call it on that widget, or you can use nested layouts.

    Note: setCentralWidget() will automatically set given widget to center and resize it when window size changes.

    Note: If you plan to use central widget as basis for adding widgets, don't do it. Because QMainWindow already has one for it's base :) .

    I hope my explanation makes any sense and answers your question.

    Regards,
    Jake



  • Hi Jake,
    Thanks for your last reply.Now its clear that I have to setup ui first.

    I still have confusion.

    First,you said :

    • And for setLayout(), it depends what you want. You probably want to call it on main window ( this). If you want widgets added to layout to be shown only in particular widget, you then call it on that widget, or you can use nested layouts.
      I dont use that central widget for that purpose only.Because as I know (correct me if I m wrong) QMAinWindow already has a layout of itself so we can not setLayout() directly on it.We have to employ an extra widget for that task.*

    And you said :

    • Note: If you plan to use central widget as basis for adding widgets, don’t do it. Because QMainWindow already has one for it’s base :) *
      I didnt understand this.QMainWindow already has what?

    Also I wonder if ui->setupUi() sets up a layout or plays a role of laying out everything else,although I do NOT explicitly add a layout by code or designer?Or, setupUi() is just a connection bridge between the code and designer form?



  • Hii!

    Yes it has a layout only if your window has from( yes, ui->setupUi() sets up a form). In that case layout will automatically be added.
    So use it on main window if you don't have a form file, otherwise, I'd recommend building as much GUI as possible from designer.

    And for second:
    I meant QMainWindow already has it's own QWidget, as it derives from it ( which actually makes it a one).

    Also if you'll look in you build directory, you'll notice ui_[classname].h files. Those are automatically built based on you ui forms and inserted into your code.


Log in to reply