Qt Ui access without source file - qt

Can I use the Qt design Form without class as kind of QMessageBox in the other source file? I have a class with source file, and a ui file without source file. In Ui namespace, I can only add header files, and not ui elements. I need to add many such dialoge boxes with QLineEdit and QPushButtons.
namespace Ui {
class MainWindow;
}

To use your .ui form you need to use uic. By launching the command uic basicform.ui it will write in the output the generated. So you can do this like that:
uic basicform.ui > ui_basicform.h
then you include the ui_basicform.h in your .cpp, and to the same than when you create a normal form class (add the ui namespace, create the ui attribute, initialize it, run the setupUi method).
For example for the Form is for a QWidget, in the mainwindow.h you have
namespace Ui {
class MainWindow;
}
add class Form;
then in attribute to the MainWindow class add Ui::Form ui_form;
After in the mainWindow.cpp the initializer list is like :
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
add ui_form(new Ui::Form)
then in the contructor you got:
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow),
ui_form(new Ui::Form)
{
ui->setupUi(this);
}
now it's like:
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow),
ui_form(new Ui::Form)
{
ui->setupUi(this);
QWidget* test = new QWidget(this);
ui_form->setupUi(test);
ui->centralWidget->layout()->addWidget(test);
}

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 );
}

How to display a widget inside a main window

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
...
}

Resources