I'm using Qt 6.4 on Visual Studio 2022, I'm trying to understand how to add a new .ui to an existing project.
For example, I have a project with a mainwindow.ui, when I open it on Qt Designer and create a new .ui window from:
[Qt Designer] File -> New -> Main Window -> Create
I added some widgets to this new window and saved it to disk with the name new_window.ui.
How do I include it in my current project? I tried #include "new_window.ui" but It throws a lot of compiler syntax errors.
What I'm trying to achieve is access the widgets from new_window.ui inside of my MainWindow class:
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent)
{
ui.setupUi(this);
// access the 'ui' from new_window.ui here
// new_window_ui.pushButton-> ...
}
I have seen that this ui generally is a private class member, there's no problem in having the new_window.ui ui public.
What is the correct way to achieve it?
I have been able to include the new ui file by creating it on a new project and copying the generated ui_new_window.h file plus her class header:
// new_window.h
#pragma once
#include "stdafx.h"
#include "ui_new_window.h"
QT_BEGIN_NAMESPACE
namespace Ui { class new_windowClass; };
QT_END_NAMESPACE
class new_window : public QWidget
{
Q_OBJECT
public:
new_window(QWidget *parent = nullptr) : QWidget(parent), ui(new Ui::new_windowClass())
{
ui->setupUi(this);
}
~new_window() { delete ui; };
Ui::new_windowClass *ui;
};
I m using Ubuntu 20.04 with Qt5.12 for developing a QT project which uses a QVTK widget to display a 3D PCL visualiser. I m facing memory leak issues after defining the visualiser and vtk widget relationship. The header file contents are as follows:
class SiLS : public QMainWindow
{
Q_OBJECT
public:
SiLS(QWidget *parent = nullptr);
~SiLS();
private:
Ui::SiLS *ui;
pcl::visualization::PCLVisualizer::Ptr viewer_3D;
};
The cpp file contents are as follows:
SiLS::SiLS(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::SiLS)
{
ui->setupUi(this);
viewer_3D.reset (new pcl::visualization::PCLVisualizer ("viewer_3D", false));
viewer_3D->setupInteractor (ui->qvtkWidget->GetInteractor (), ui->qvtkWidget->GetRenderWindow ());
ui->qvtkWidget->SetRenderWindow(viewer_3D->getRenderWindow());
}
SiLS::~SiLS()
{
delete ui;
}
Only these 3 lines of code in constructor is giving lot of memory leak issues. Following screenshot shows few of the leaks identified by valgrind in Qt creator.
SiLS.cpp:10:0 represents the following line in cpp file:
viewer_3D.reset (new pcl::visualization::PCLVisualizer ("viewer_3D", false));
Using latest QT 5.15.0, c++20, cmake 3.17, MSVC 16.7.2
I have a simple QWidget: (all necessary includes defined in precompiled header)
widget.h
#pragma once
#ifndef _WIDGET_H_209323
#define _WIDGET_H_209323
class TestWidget: public QWidget {
Q_OBJECT
public:
explicit TestWidget(QWidget* parent = nullptr);
private:
QVBoxLayout* side_panel_;
private:
auto init_elements() -> void;
};
#endif
widget.cpp:
#include "widget.h"
TestWidget::TestWidget(QWidget* parent) : QWidget(parent) {
init_elements();
}
auto TestWidget::init_elements() -> void {
auto init_main_panel = [this]() {
side_panel_ = new QVBoxLayout();
QPushButton* main_view = new QPushButton("test");
side_panel_->addWidget(main_view);
};
init_main_panel();
this->setLayout(side_panel_);
}
The program compiles fine, but crashes at startup with Process finished with exit code -1073741511 (0xC0000139) and nothing else.
Changing QPushButton to any other widget, for example
QLabel* label = new QLabel(this);
label->setText("test");
side_panel_->addWidget(label);
works as expected, without any problems.
Actually just adding widget.h with QPushButton to CMakeLists.txt add_target, without including it in any other project files crashes the program at startup.
UPDATE:
Tried loading project into Visual Studio and got more meaningful error:
The procedure entry point
?hitButton#QPushButton##MEBA_NAEBVQPoint###Z
could not be located int the dynamic link library
UPDATE 2:
Changing QT version to 5.14.2 fixes this issue. Both versions installed as MSVC precompiled 64-bit (MSVC2017 for 5.14 and MSVC2019 for 5.15) from official QT installer.
I started to use QtCharts in my application. The chart that I am considering is a Line Chart, using the objects QChart and QLineSeries. As all the points are added dynamically, I use the signal/slot system to update the chart:
QLineSeries* serie = new QLineSeries(this);
connect(serie, SIGNAL(pointAdded(int)), this, SLOT(onPointAdded(int)));
void MyChart::onPointAdded(int index) {
// Delete the first items if the number of points has reached a threshold
while (serie->points().length() >= threshold)
serie->remove(0);
}
The function onPointAdded is called when a point is added in serie (a QLineSeries object). The code snippet that I gave removes the first points in serie such as the number of points in the graph is always fixed (except at the beginning).
When I run this code in Release, there is no problem. However, when I run it on Debug and the number of points reaches the threshold, I obtain the following error message:
This dialog box does not stop the program, but each time a point is added (and reach the threshold) a new dialog box appears on top of the previous one.
The following is the minimal code to reproduce the error:
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QChart>
#include <QLineSeries>
#include <QMainWindow>
#include <QValueAxis>
#include <QtCharts/QChart>
#include <QtCharts/QLineSeries>
QT_CHARTS_USE_NAMESPACE
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = nullptr);
~MainWindow();
private:
Ui::MainWindow *ui;
QChart* chart = nullptr;
QLineSeries* serie = nullptr;
int threshold = 5;
private slots:
void onAddPointButtonClicked();
void onPointAdded(int index);
};
#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent), ui(new Ui::MainWindow) {
ui->setupUi(this);
chart = new QChart;
serie = new QLineSeries(this);
connect(ui->bt_addPoint, SIGNAL(clicked()), this, SLOT(onAddPointButtonClicked()));
connect(serie, SIGNAL(pointAdded(int)), this, SLOT(onPointAdded(int)));
chart->legend()->hide();
chart->addSeries(serie);
ui->graphicsView->setChart(chart);
}
MainWindow::~MainWindow() {
delete ui;
}
void MainWindow::onAddPointButtonClicked() {
serie->append(0, 1);
}
void MainWindow::onPointAdded(int index) {
while (serie->points().length() >= threshold)
serie->remove(0);
}
I used an UI Form to generate the graphical interface. This interface contains a QChartView and a QPushButton (to add dynamically the points).
My Qt version is 5.11.2, and the bug has been produced using MSVC 2017 64-bits. The plugin QtCharts is needed to use the QChart, QChartView and QLineSeries.
I would like to know if it is possible to either fix this problem or to disable the Qt Debug Dialog Messages.
Cause
It is not a bug, but an expected result of the order in which the slots MainWindow::onPointAdded (in your code) and XYChart::handlePointAdded are executed. Here is the whole story:
From the error message it becomes clear, that in the file xychart.cpp on line 142 the check of index against the count of m_series fails. The thing, which invalidates the check, is your serie->remove(0);. The reason is that your slot is executed before the slot, where the check is made, because your connect statement comes first. The question is: first to what? Well, this is the tricky part and I have to admit that it is indeed not immediatelly obvious. However, with some digging in the source code, one could get to the bottom of the problem. The path is the following:
chart = new QChart; in your code instantiates a QChart, which in turn instantiates a PIMPL QChartPrivate
QChartPrivate connects in it's constructor ChartDataSet::seriesAdded to ChartPresenter::handleSeriesAdded:
QObject::connect(m_dataset, SIGNAL(seriesAdded(QAbstractSeries*)), m_presenter, SLOT(handleSeriesAdded(QAbstractSeries*)));
IMPORTANT Now you connect QLineSeries::pointAdded to MainWindow::onPointAdded
chart->addSeries(serie); in your code causes the ChartPresenter::handleSeriesAdded slot to be executed, where QLineSeriesPrivate::initializeGraphics is called:
series->d_ptr->initializeGraphics(rootItem());
In QLineSeriesPrivate::initializeGraphics a LineChartItem is instantiated:
LineChartItem *line = new LineChartItem(q,parent);
LineChartItem calls the constructor of its base class XYChart in the initializer list of its own constructor
IMPORTANT Only now is the connect statement executed, which causes the troublesome for you XYChart::handlePointAdded slot to be called when a point is added to the series:
QObject::connect(series, SIGNAL(pointAdded(int)), this, SLOT(handlePointAdded(int)));
Focusing only on the steps marked as important, it becomes obvious in which order do both connect statements come. This is also the order in which the respective slots are called.
Solution
Having this cause in mind, I would suggest you to first add the series to the chart and then connect the pointAdded signal, i.e.:
move
connect(serie, SIGNAL(pointAdded(int)), this, SLOT(onPointAdded(int)));
anywhere after
chart->addSeries(serie);
I'm working on an app in C++/Qt I have used the design tool to design a Qdialog box.
The Dialog box is defined as below.
c++ file
#include "dialogwarning.h"
#include "ui_dialogwarning.h"
DialogWarning::DialogWarning(QWidget *parent) :
QDialog(parent),
ui(new Ui::DialogWarning)
{
ui->setupUi(this);
}
DialogWarning::~DialogWarning()
{
delete ui;
}
header file
#include <QDialog>
namespace Ui {
class DialogWarning;
}
class DialogWarning : public QDialog
{
Q_OBJECT
public:
explicit DialogWarning(QWidget *parent = 0);
~DialogWarning();
private:
Ui::DialogWarning *ui;
};
The source use it as below:
WarningDialog = new DialogWarning();
QLabel *label = new QLabel("File/Folder name already exist", WarningDialog);
label->setGeometry(WarningDialog->rect().center().x() - label->rect().width()/2,
WarningDialog->rect().center().y() - label->rect().height()*2,
WarningDialog->rect().width(),
WarningDialog->rect().height());
WarningDialog->exec();
I'm using exec instead of show because the exec primitive allow me to be stucked inside the dialog until a press on the "Ok" button.
What is strange is that the OK button is not working. I do not need any specific behavior just wait the OK press to continue to run the code.
Thanks
i'm not quite sure assuming u have connected everything. could be that the application is frozen.
why not put the calculation in a different thread and connect the same signal that shows the dialog to thread pause.
the signal of the ok pushbutten should be connected to close the dialog and thread resume...