How to display a widget inside a main window - qt

I have a project marines and i have the following files structure.
marines.pro
FORMS
iran.ui
marines.h
Headers
iran.h
marines.h
Sources
iran.cpp
main.cpp
marines.cpp
I added the widget iran in the project marines.
Here is marines.cpp
#include <QtGui>
#include "marines.h"
#include "iran.h"
marines::marines(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::marines)
{
ui->setupUi(this);
connect(ui->actionExit, SIGNAL(triggered()), this, SLOT(close()));
connect(ui->actionIran, SIGNAL(triggered()), this, SLOT(ir()));
}
void marines::ir()
{
//slot to display iran ui inside my main window
}
marines::~marines()
{
delete ui;
}
and here is my iran.cpp
#include "iran.h"
#include <QtGui>
iran::iran(QWidget *parent) :
QWidget(parent),
ui(new Ui::iran)
{
ui->setupUi(this);
}
iran::~iran()
{
delete ui;
}
How can i display the widget iran i made in qt designer?.

It all depends on how you want the widget to be displayed.
you could add a layout to your central widget in your MainWindow and add your custom widget to the layout
if you want your custom widget to be centralWidget of the MainWindow then use setCentralWidget
If you want the custom widget as a subWindow then add MdiArea to your MainWindow. Then add custom widget to you MdiArea.
If you just want the custom widget to be displayed as a window then just "widget.show()"
Its better to look at Qt's examples to understand how a MainWindow is used.

marines::marines(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::marines)
{
ui->setupUi(this); // after this
iran *ir = new iran(); // create variable ir
ir->show(); // show window
...
}

Related

Qt segfault trying to show 2 dialogs in test application

I'm just learning Qt. I reproduced my problem in a simple test application. I created a new project. Added 2 dialogs Dialog1 and Dialog2. I added 2 menu entries to call dialog1 and dialog2.
The main window's header file looks like this:
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include "dialog1.h"
#include "dialog2.h"
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
private slots:
void on_actiondialog1_triggered();
void on_actiondialog2_triggered();
private:
Ui::MainWindow *ui;
Dialog1 *mDialog1;
Dialog2 *mDialog2;
};
#endif // MAINWINDOW_H
The main window's cpp looks like this:
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_actiondialog1_triggered()
{
if (!mDialog1) {
mDialog1 = new Dialog1(this);
mDialog1->setModal(false);
}
mDialog1->show();
mDialog1->activateWindow();
}
void MainWindow::on_actiondialog2_triggered()
{
if (!mDialog2) {
mDialog2 = new Dialog2(this);
mDialog2->setModal(false);
}
mDialog2->show();
mDialog2->activateWindow();
}
So it is basically as empty as it gets... If I only show one dialog by commenting out the relevant sections it works but as soon as I want to use 2 or more is segfaults. The given dialogs constructor isn't even being called anymore.
I am using:
Qt Creator 4.12.3
Based on Qt 5.14.2 (GCC 5.3.1 20160406 (Red Hat 5.3.1-6), 64 bit)
Built on Jun 16 2020 04:15:35
I don't understand what I'm doing wrong. Can someone please clarify?
First, it is not about Qt. It is about your implementation:In your constructor, I don't see code, which initializes mDialog1 and mDialog2.
So, when go to the slot what is the value of mDialog1 ? It is undefined, especially in Release build.
Here is one of the approaches:
In your constructor, just create the objects:
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
mDialog1 = new Dialog1(this);
mDialog2 = new Dialog2(this);
}
Then in slot (you don't need to check the pointer):
void MainWindow::on_actiondialog1_triggered()
{
mDialog1->setModal(false); //Not required, because of show()
mDialog1->show();
mDialog1->activateWindow();
}
Another approach, which creates objects on demand:
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
//Initalize these members
m_dialog1 = nullptr;
m_dialog2 = nullptr;
}
And then:
void MainWindow::on_actiondialog2_triggered()
{
if (!mDialog2)
{
mDialog2 = new Dialog2(this);
mDialog2->setModal(false);
}
mDialog2->show();
mDialog2->activateWindow();
}

How to connect LineEdit and PushButton in Qt?

I created a .ui file using Qt Designer and in the file I created a PushButton which is disabled initially, I also have a LineEdit. I want to connect LineEdit and PushBotton so that when text changed in LineEdit , the PushButton will be enabled, But I don't find any such option in Signals and slots. Can anyone help?
You have to write a custom slot (which is pretty easy).
Add this to your MainWindow declaration (.h file):
private slots:
void checkInput(const QString &text);
Your .cpp file:
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow)
{
ui->setupUi(this);
connect(ui->lineEdit, SIGNAL(textChanged(QString)), this, SLOT(checkInput(QString)));
}
void MainWindow::checkInput(const QString &text)
{
ui->pushButton->setEnabled(!text.isEmpty());
}
To add this slot to Qt Designer, do the following:
Right click on your MainWindow, "Change signals/slots";
Add your custom slot ("Plus" button) by entering checkInput();
After this you will be able to connect your custom slot via Qt Designer.
In Qt 5, you generally don't need trivial private slots and should use lambdas instead:
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow)
{
ui->setupUi(this);
connect(ui->lineEdit, &QLineEdit::textChanged, [this](const QString & text) {
ui->pushButton->setEnabled(!text.isEmpty());
});
...
}

Qt: why adding layout to MainWindow (by code) didn't work but adding as CentralWidget worked?

I have coded a QWidget MyWidget and I wanted to add two MyWidget with QVBoxLayout in the MainWindow class (the same MainWindow which is provided default when we open Qt Creator). So, what I did was, in the constructor of MainWindow, I took two pointers of MyWidget, make in point to an instances of the same class, then added the widgets to a QVBoxLayout and called setLayout, but when I ran the code, the ui contained nothing!
Demonstration code (didn't work):
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QLayout>
#include "mywidget.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
QVBoxLayout *layout;
layout=new QVBoxLayout();
MyWidget *a=new MyWidget(),*b=new MyWidget();
layout.addWidget(a);
layout.addwidget(b);
setLayout(layout);
}
But MainWindow showed nothing. Now, according to this answer, I have to add layout to a widget and then set the new widget as a central widget of the MainWindow. I did that and that worked.
New demonstration code (Worked):
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QLayout>
#include "mywidget.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
QVBoxLayout *layout;
layout=new QVBoxLayout();
MyWidget *a=new MyWidget(),*b=new MyWidget();
layout.addWidget(a);
layout.addwidget(b);
QWidget *window=new QWidget();
window.setLayout(layout);
setCentralWidget(window);
}
My question is why?
The reason is clearly described by QMainWindow documentation:
QMainWindow has its own layout to which you can add QToolBars,
QDockWidgets, a QMenuBar, and a QStatusBar. The layout has a center
area that can be occupied by any kind of widget.
and
Note: Creating a main window without a central widget is not
supported. You must have a central widget even if it is just a
placeholder.

CentralWidget adjust size to show all the content

I'm a beginner with Qt and I haven't understand yet the layout on centralWidget.
I have a custom QWidget subclass (with a .ui and the cpp class) that I want to add to the central Widget.
I'd like to understand how to say to the QMainWindow subclass to resize and fit the content whenever I add something.
I've tried with adjustSize method both on mainwindow and on centralWidget objects but nothing change..
Anyway, I'm adding the widget in this way:
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
MyWidget *w = new Undistort();
w->setParent(this->centralWidget());
}
some advice?
Given example, depending on Pixmap size, QMainWindow will resize. Generally this is not the ideal case, as a user MainWindow need to display on the desktop, It should not be more that your desktop screen size. I am not sure you are actually looking for this. Copied fromSO Ans
#include "mainwindow.h"
#include <QLabel>
#include <QHBoxLayout>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindowClass)
{
ui->setupUi(this);
QPixmap pix;
pix.load("C:\\Users\\user\\Desktop\\Uninstallation failure2.png");
//Replace with ImageLabel2
QLabel* image = new QLabel(this);
image->setPixmap(pix);
QHBoxLayout* hbox = new QHBoxLayout(this);
hbox->addWidget(image);
QWidget* centreWidget = new QWidget();
//QMainwindow, having a feature called centreWidget, to set the layout.
centreWidget->setLayout( hbox );
setCentralWidget( centreWidget );
}

Centering widgets in a dynamic layout?

I'm using the answer to this SO question to make a custom image widget which automatically scales correctly. It works fine but now I am trying to center the image widget instance at the center of my main window.
My idea was to create a QHBoxLayout, add the image widget to that and then add the hBox instance to the ui->verticalLayout.
Doesn't work. The image still displays flush left with the error message: QLayout: Attempting to add QLayout "" to MainWindow "MainWindow", which already has a layout
I then tried a few variations on 'setAlignment` but then the image doesn't appear at all. My simple test code is below.
What am I missing here?
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
QPixmap pix;
pix.load("/Users/home/Desktop/test.jpg");
ImageLabel2* image = new ImageLabel2(this);
image->setPixmap(pix);
QHBoxLayout* hbox = new QHBoxLayout(this);
hbox->addWidget(image);
// hbox->setAlignment(image,Qt::AlignCenter);
hbox->setAlignment(Qt::AlignHCenter);
// ui->verticalLayout->addLayout(hbox);
ui->verticalLayout->addLayout(hbox);
// ui->verticalLayout->addWidget(image);
// ui->verticalLayout->setAlignment(image,Qt::AlignCenter);
// ui->verticalLayout->setAlignment(Qt::AlignHCenter);
}
Try this:
QHBoxLayout* hbox = new QHBoxLayout(this);
hbox->addStretch();
hbox->addWidget(image);
hbox->addStretch();
None of the suggestions here worked for me. Don't know why and it seems hard to debug layout problems
However a reply to my question on the Qt Project.org site works perfectly. So not my solution but I am posting it here since this "centering/resizing image" issue seems a common problem.
class CustomWidget : public QWidget {
public:
CustomWidget(const QPixmap &p, QWidget* parent = 0)
: QWidget(parent), pixmap(p) {}
void paintEvent(QPaintEvent * e)
{
QRect srcRect(QPoint(), pixmap.size());
QSize dstSize = srcRect.size().scaled(
e->rect().size(), Qt::KeepAspectRatio);
QRect dstRect(QPoint((width() - dstSize.width())/2,
(height() - dstSize.height())/2), dstSize);
QPainter p(this);
p.setRenderHint(QPainter::Antialiasing);
p.drawPixmap(dstRect, pixmap, srcRect);
}
private:
QPixmap pixmap;
};
and then in the main window:
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
setCentralWidget(new CustomWidget(QPixmap("test.png")));
}
main window(QMainwindow) API setCentralWidget to align the widget on center.
Note:Concept of centrewidget, is to differentiate the docking area( Left, Right, Bottom, Top ).
with out a centre how some one know who is where. when we are developing with QMainWindow, you can see in UI_MainWindow.h, setting Centrewidget with dummy QWidget
Below code will work
#include "mainwindow.h"
#include <QLabel>
#include <QHBoxLayout>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindowClass)
{
ui->setupUi(this);
QPixmap pix;
pix.load("C:\\Users\\user\\Desktop\\Uninstallation failure2.png");
//Replace with ImageLabel2
QLabel* image = new QLabel(this);
image->setPixmap(pix);
QHBoxLayout* hbox = new QHBoxLayout(this);
hbox->addWidget(image);
QWidget* centreWidget = new QWidget();
//QMainwindow, having a feature called centreWidget, to set the layout.
centreWidget->setLayout( hbox );
setCentralWidget( centreWidget );
}
MainWindow::~MainWindow()
{
}

Resources