How can I restore the initial centralwidget of the QMainWindow? - c++

I am kinda of new to Qt and decided to play around with it a bit so that one day I may be able to make some programs with a GUI. I've been playing around with windows and encountered a problem. I created two new QWidget Form classes in addition to the QMainWindow. With one of them, I was able to make a separate window popup and disappear. What I am trying to do with the second one is this...
I have a MainWindow with a button, and when that button is pressed, the CentralWidget changes to the QWidget with another button. Then, when I press a button on the new button, it restores the CentralWidget to the original one.
I did try storing the initial CentralWidget before changing it but I have yet to be able to successfully restore it. I do know about QStackedWidget, but I would like to know if there is another way of doing it. THANK YOU!

It seems Qt deletes child widget, when new one assigned as child widget. The fallowing code illustrates it and shows workaround
class QMyWidget: public QWidget
{
public:
~QMyWidget(){std::cout<<"Destroyed"<<std::endl;}
};
class QMyWidget2: public QWidget
{
public:
~QMyWidget2(){std::cout<<"Destroyed2"<<std::endl;}
};
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
this->setCentralWidget(new QMyWidget());
this->setCentralWidget(new QWidget);
QWidget * w = new QMyWidget2();
this->setCentralWidget(w);
w->setParent(NULL);
this->setCentralWidget(new QWidget);
}
MainWindow::~MainWindow()
{
delete ui;
}

Do you want QStackedWidget? It's a but like QTabWidget but without the, er, tabs.

Related

Change QMainWindow layout programmatically in c++

I am using Creator to build main MainWindow and I populate it with all my widgets.
I do not set any MainWindow lay out in this stage (like "Lay out in a Grid" or "Lay out Horizontally".
When I launch the Application I want to dynamically change the MainWindow layout of widgets in it to "Lay out in a Grid" like in Creator mode by pressing the left button.
I’ve tried hard all possible combinations reading many posts around.
this solution:
Qt: Can't set layout in QMainWindow
doesn't work and it does not make much sense to me.
I've tried:
QGridLayout * MainWindowLayout = new QGridLayout;
ui->setupUi(this);
centralWidget()->setLayout(MainWindowLayout);
NO LUCK
I've tried to put all my widgets inside a big widget at desegn time named MainWindowWidget and then setting it as a centralWidget
QGridLayout * MainWindowLayout = new QGridLayout;
ui->setupUi(this);
setCentralWidget(ui->MainWindowWidget);
centralWidget()->setLayout(MainWindowLayout);
NO LUCK
Ain't there any way to change the MainWindow widget's layout like "Lay ouy in a Grid" at design time when using the Creator??
EDIT:
To be more specific with NO LUCK I mean that the widgets are not placed as in a grid as expected.
Here is a code snipped that you can try on an empty application
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
/*
Place some widgets at design time with Creator (at least 2) in the MainWindow form
in a misplaced order and do not apply any "Lay out xxx" right button on QT Creator
*/
ui->setupUi(this);
/* HERE I WANT THE MainWindow or either an Object to take a specific Layout */
QGridLayout * MainWindowLayout = new QGridLayout;
ui->setupUi(this);
centralWidget()->setLayout(MainWindowLayout);
}
It is almost 2 days that I am googling and I can't find any way out
Thank you all for your help...
You are creating the layout But you are not adding widgets to it. This should fix your issue:
ui->setupUi(this);
QGridLayout *MainWindowLayout = new QGridLayout();
MainWindowLayout->addWidget(ui->label, 0, 0);
MainWindowLayout->addWidget(ui->label_2, 0, 1);
// Add all other widgets to your layout...
centralWidget()->setLayout(MainWindowLayout);
#C137
Finally I got it working doing the following:
I places all my form widgets into 3 different widgets (containers QFrame in my case).
Then I placed them into the Layout as suggested and it worked.
This solution is a bit tricky
QGridLayout *MainWindowLayout = new QGridLayout();
MainWindowLayout->addWidget(ui->MainFrame, 0, 0); // MainFrame --> My new object containing other widgets
MainWindowLayout->addWidget(ui->DebugButtonsFrame, 0, 1); // DebugButtonsFrame as above
MainWindowLayout->addWidget(ui->DebugMemoFrame, 1, 0); // DebugMemoFrame as above
// Add all other widgets to your layout...
centralWidget()->setLayout(MainWindowLayout);
QT is handling this task in its own way a bit confusing from my point of view. While I was using Embarcadero the Layout were much much easier to manage.
I thought there could me a method to easily set the MainWindow Layout as in Creator mode which was much much easier and faster to handle.
So far it worked as expected but still confusing.
Thank you all for the support.

How to add a widget into central Widget using code in Qt

I need to add a widget to the form using code, but don't by use QHBoxLayout or QVBoxLayout.
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
fields[0] = new CustomLabel();
fields[0]->setText("Hello");
//how to show it
}
You can simply use setCentralWidget()
documentation of setCentralWidget()
like this ui->setCentralWidget(fields[0]); or maybe with this replacing ui
But, to displayed many widget you have to use a widget that contains the matrix of labels (widget). When you have the parent widget that contain the matrix display it with setCentralWidget()

Qt Creator Align button float to the top

I have this gridlayout added onto my centralWidget of my UI in Qt Creator. And I wanted to add several buttons onto the gridlayout. My code is as follows:
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
QPushButton *button1 = new QPushButton();
button1->setText("hello");
ui->gridLayout->addWidget(button1, 0,0);
}
MainWindow::~MainWindow()
{
delete ui;
}
Even though the button is added, it is seen appearing in the middle of the UI when the program is run. And there is a huge gap between the menu bar and button. How do i go about adding the button so that the button will flow nicely below the menu bar?
Please advice.
Thanks
The grid layout was placed in the middle of the UI in design mode, so anything you place inside will fill the fixed rectangle of the grid layout.
To make the grid layout fill the main window, right click the main window and click Lay out > Lay out vertically.
You can also fix the huge gap by placing a vertical spacer below the grid layout.
I guess this method work as well. By setting the alignment for the addWidget portion.
eg: ui->gridLayout->addWidget(button1, 0,0, Qt::AlignTop);

Can you add a toolbar to QDialog?

I'm working on a project that needs to call a modal window with a toolbar to do some work on some data before it's loaded. The reason I need the toolbar is the user has a few different possible options that can be combined.
The obvious choice here is a Modal dialog (which I have working right now). The issue is I want a toolbar. This is a two part question:
Is it possible to add a toolbar to a QDialog? (also is it possible to do this in Qt Designer?)
If 1. is not possible, how can I make a QMainWindow modal?
You can simply use the setMenuBar function of the layout manager that is installed on your QDialog:
myDialog->layout()->setMenuBar(myMenuBar);
If you don't need the built-in drag and drop feature of QMainWindow's toolbars, you can simply add a QToolBar to any layout, including QDialog's layout(). See the DigviJay Patil's answer below for details, which is definitely cleaner conceptually.
Otherwise, please read on.
It is not directly possible to add a QToolBar to a QDialog in the QMainWindow::addToolBar() sense, because QDialog inherits only QWidget and not QMainWindow, as you noted (hence do not have the method addToolBar())
You can't make a QMainWindow modal, but you can insert a QMainWindow in a QDialog this way:
Code:
MyDialog::MyDialog() :
QDialog()
{
QMainWindow * mainWindow = new QMainWindow(); // or your own class
// inheriting QMainWindow
QToolBar * myToolBar = new QToolBar();
mainWindow->addToolBar(myToolBar);
QHBoxLayout * layout = new QHBoxLayout();
layout->addWidget(mainWindow);
setLayout(layout);
}
Indeed, a QMainWindow doesn't necessarily have to be a top-level widget, and you can even insert several QMainWindows as children of a single widget (may not be the wisest choice though, as the user would probably be confused with the separate sets of menu bars, toolbars, dock widgets, etc.).
You can add QToolBar in QDialog. But as a QWidget. Please have a look
MyDialog::MyDialog(QWidget *parent) : QDialog(parent)
{
QVBoxLayout *mainLayout = new QVBoxLayout(this);
QToolBar *toolBar = new QToolBar();
mainLayout->addWidget(toolBar);
QAction *action1 = new QAction("Add", toolBar);
QAction *action1 = new QAction("Del", toolBar);
//Add What you want
}
As QToolBar is child of QWidget we can add it as Widget. Using Layout you can adjust its position. Please check this link http://developer.nokia.com/community/wiki/How_to_use_QToolBar_and_QToolButton_in_Qt

Qt Widget does not show

I create a class which is a subclass of a QWidget used for painting a image, only for painting a image, named ImageWidget.
When I only create a ImageWidget and call ImageWidget.show(), everything is fine. Then I create another QWidget subclass like below. At present, only shows the combox and slider, the image does not show. Could someone help me about it?
MainWindow::MainWindow(QWidget *parent) :
QWidget(parent)
{
imgWidget=new ImageWidget(this);
fractalTypeLabel=new QLabel(tr("Type"));
typeCombo=new QComboBox();
typeCombo->addItem(tr("One"));
typeCombo->addItem(tr("Two"));
scalefactorLabel=new QLabel(tr("Scale Factor"));
scalefactorSlider=new QSlider(Qt::Horizontal);
scalefactorSlider->setTickInterval(1);
scalefactorSlider->setTickPosition(QSlider::TicksBelow);
QVBoxLayout *imageLayout=new QVBoxLayout();
imageLayout->addWidget(imgWidget);
QGridLayout *gridLayout=new QGridLayout;
gridLayout->addWidget(fractalTypeLabel,0,0);
gridLayout->addWidget(typeCombo,0,1);
gridLayout->addWidget(scalefactorLabel,1,0);
gridLayout->addWidget(scalefactorSlider,1,1);
QHBoxLayout *mainLayout=new QHBoxLayout;
mainLayout->addLayout(imageLayout);
mainLayout->addLayout(gridLayout);
this->setLayout(mainLayout);
}
Best Regards,
Most Likely you are not reporting a size for your widget from sizeHint, in your custom subclass implement virtual QSize sizeHint () const and return something. Your widget will probably show. In the absence of sizeHint the system thinks that your widget can be of size 0x0 and eliminates it from the layout. There are other ways around this by playing with the layout settings. It is slightly non-intuitive ... . You might want to implement some of the other size related functions in from QWidget