Close QWebEngineProcess.exe - c++

I have a problem that, after closing a QDialog with web content, the QWebEngineProcess.exe process is not closing.
Here is a minimal example:
#include <QApplication>
#include <QWebEngineView>
#include <QWebEngineSettings>
#include <QDialog>
#include <QMainWindow>
#include <QLayout>
#include <QtGui>
#include <QPushButton>
class Dialog : public QDialog
{
public:
Dialog() : QDialog(nullptr)
{
resize(512, 512);
setAttribute(Qt::WA_DeleteOnClose);
auto verticalLayout = new QVBoxLayout(this);
verticalLayout->setSpacing(0);
verticalLayout->setContentsMargins(0, 0, 0, 0);
m_webView = new QWebEngineView(this);
verticalLayout->addWidget(m_webView);
}
void openPage(const QUrl& url)
{
m_webView->setUrl(url);
}
private:
QWebEngineView* m_webView;
};
class MainWindow : public QMainWindow
{
public:
MainWindow() : QMainWindow(nullptr)
{
resize(512, 512);
QPushButton* btn = new QPushButton("open web dialog", this);
connect(btn, &QPushButton::clicked, [this] ()
{
if (m_dialog == nullptr)
{
m_dialog = new Dialog();
m_dialog->openPage(QUrl("https://www.qt.io"));
m_dialog->show();
}
});
}
private:
QPointer<Dialog> m_dialog;
};
int main(int argc, char *argv[])
{
QCoreApplication::setOrganizationName("QtExamples");
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QApplication app(argc, argv);
MainWindow window;
window.show();
return app.exec();
}
I'm expecting that, after the dialog is closed, QWebEngineProcess.exe will be closed too, because I'm not using webengine anymore.
P.S. During opening WebPage, I have 2 QWebEngineProcess.exe. One is disappearing, but the second one left.

For any QObject instances (such as QDialog and QWebEngineView), the destructor of a parent object destroys all child objects. This means, for every object you new, it must either have a parent, or you must delete it manually, otherwise you are creating a leak and objects will remain open (not deleted).
You are creating a QWebEngineView object with the correct parent, but the parent (the Dialog) doesn't have a parent (you initialize the parent to nullptr). This means the Dialog would delete the QWebEngineView, except it never is deleted itself.
To fix it, either delete the Dialog (stored in m_dialog) manually in the MainWindow destructor (not recommended), or initialize it correctly with the MainWindow as its parent.
This may also be related to a bug in Qt 5.11 and 5.12. If this is the problem, the recommended solution is to add QCoreApplication::setAttribute(Qt::AA_UseOpenGLES); at the top of your main() function (before declaring the QApplication).

Related

why do i have memory leak while doing inheritance of QWidget class in Qt

I am new to c++. I am trying to design one class by inheriting base class QWidget
but I am getting memory leak while creating this class via new.
here below I have my code snippet of class and main application
#include "QWidget"
#include "QDebug"
#include "ui_myobject.h"
namespace Ui {
class MyObject;
}
class MyObject : public QWidget{
Q_OBJECT
public:
explicit MyObject();
~MyObject();
Ui::MyObject *ui;
};
#include "myobject.h"
#include "ui_myobject.h"
MyObject::MyObject() : QWidget(),ui(new Ui::MyObject){
ui->setupUi(this);
qDebug() << "MyObject Initilised";
}
MyObject::~MyObject(){
delete ui;
qDebug() << "MyObject Deinitilised";
}
class Application : public QWidget
{
Q_OBJECT
public:
explicit Application(QWidget *parent = 0);
~Application();
MyObject *m_MyObject;
};
Application::Application(QWidget *parent) :QWidget(parent),ui(new Ui::Application){
ui->setupUi(this);
}
i am calling this below function via click release slot of button
void somefunction()
{
m_MyObject = new MyObject();
//mAlarm_main->Alarm();
m_MyObject->show();
delete m_MyObject;
}
int main(int argc, char *argv[])
{
#if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0))
; // Qt5 uses different graphical backend
#else
QApplication::setGraphicsSystem("raster");
#endif
QApplication a(argc, argv);
Application w;
// uncomment this line to remove window frame
//w.setWindowFlags(Qt::FramelessWindowHint);
w.setGeometry(0,0,800,480);
w.show();
return a.exec();
}
When I call somefunction I have memory leak in my app I am watching its stack size using top command it continuously increase by 2 mb after 200 timesmy application crashes. I am deleting my object but still some memory leaks occure is there any different way to delete QWidget
If i don't call m_MyObject->show(); function than memory leaks not happen.
In the following piece of code you delete just shown widget (method `show' is not blocking). I believe it causes undefined behavior and, probably, the memory leak you are worrying about:
m_MyObject = new MyObject();
m_MyObject->show();
delete m_MyObject;
Assuming that you need only one MyObject in a time, I would suggest to create MyObject only once (don't forget to initialize it with nullptr by default)
if (!m_MyObject)
m_MyObject = new MyObject();
m_MyObject->show();
Another way (looks like this widget is supposed to be shown as a separate window) is to set Qt::WA_DeleteOnClose attribute (see QWidget::close for details).
m_MyObject = new MyObject();
m_MyObject->setAttribute(Qt::WA_DeleteOnClose, true);
m_MyObject->show();
Example:
#include <QApplication>
#include <QPushButton>
int main(int argc, char* argv[])
{
QApplication app(argc, argv);
QWidget* w = nullptr;
QPushButton b;
b.setText("Button");
b.connect(&b, &QPushButton::clicked, [&w]() {
w = new QWidget();
w->setAttribute(Qt::WA_DeleteOnClose, true); // ADD THIS LINE
w->show();
// delete w; // DON'T DO IT
});
b.show();
return app.exec();
}

Class inherited from QLabel, why custom slot is not called?

I made class inherited from QLabel. This class also have public slot, that should change label caption. I "call" this SLOT with clicked() SIGNAL of button.
So nothing happened when I press the button.
#include <QApplication>
#include <QLabel>
#include <QPushButton>
class Label : public QLabel
{
public:
Label(QString a) : QLabel(a){}
public slots:
void change()
{
this->setNum(2);
}
};
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QPushButton* button = new QPushButton("Button");
Label* lbl = new Label("Label");
button->show();
lbl->show();
QObject::connect(button, SIGNAL(clicked(bool)), lbl, SLOT(change()));
return a.exec();
}
What should I do to change caption from slot?
In order for the signals and slots to be recognized, the classes must use the Q_OBJECT macro in the private part.
Another thing to do is to include "main.moc", for more information on this point read this.
#include <QApplication>
#include <QLabel>
#include <QPushButton>
class Label : public QLabel
{
Q_OBJECT
public:
Label(const QString &text, QWidget *parent = Q_NULLPTR, Qt::WindowFlags f = Qt::WindowFlags()) :
QLabel(text, parent, f){}
public slots:
void change()
{
setNum(2);
}
};
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QPushButton* button = new QPushButton("Button");
Label* lbl = new Label("Label");
button->show();
lbl->show();
QObject::connect(button, SIGNAL(clicked()), lbl, SLOT(change()));
return a.exec();
}
#include "main.moc"
At the end of making these changes you must execute the following:
Press clean all in the Build menu.
then run qmake in the same menu.
And you just compose your project.
Add Q_OBJECT after
class Label : public QLabel
{
and then you should
either place your Label class declaration to a .h file or write #include "main.moc" after main function declaration.
try to get the return value from your connect call an check it for true or false.
Add Q_OBJECT Macro to the beginning of your derived class.
Add some debug output to your slot like
qDebug()<<"This is my slot.";
Maybe this would help to get a little further.
Best regards

when should the child object be declared as a member variable of its parent class in qt?

//disconnect.h
#include <QWidget>
#include <QPushButton>
class Disconnect : public QWidget {
Q_OBJECT
public:
Disconnect(QWidget *parent = 0);
private slots:
void onClick();
void onCheck(int);
private:
QPushButton *clickBtn;
};
//disconnect.cpp
#include <QTextStream>
#include <QCheckBox>
#include <QHBoxLayout>
#include "disconnect.h"
Disconnect::Disconnect(QWidget *parent)
: QWidget(parent) {
QHBoxLayout *hbox = new QHBoxLayout(this);
hbox->setSpacing(5);
clickBtn = new QPushButton("Click", this);
hbox->addWidget(clickBtn, 0, Qt::AlignLeft | Qt::AlignTop);
QCheckBox *cb = new QCheckBox("Connect", this);
cb->setCheckState(Qt::Checked);
hbox->addWidget(cb, 0, Qt::AlignLeft | Qt::AlignTop);
connect(clickBtn, &QPushButton::clicked, this, &Disconnect::onClick);
connect(cb, &QCheckBox::stateChanged, this, &Disconnect::onCheck);
}
void Disconnect::onClick() {
QTextStream out(stdout);
out << "Button clicked" << endl;
}
void Disconnect::onCheck(int state) {
if (state == Qt::Checked) {
connect(clickBtn, &QPushButton::clicked, this, &Disconnect::onClick);
} else {
disconnect(clickBtn, &QPushButton::clicked, this,
&Disconnect::onClick);
}
}
//main.cpp
#include <QApplication>
#include "disconnect.h"
int main(int argc, char *argv[]) {
QApplication app(argc, argv);
Disconnect window;
window.resize(250, 150);
window.setWindowTitle("Disconnect");
window.show();
return app.exec();
}
In the above code,A Disconnect object has two child object——a QPushButton and a QcheckBox, but class Disconnect only have a QPushButton pointer, not a QcheckBox pointer. Can anyone tell me when should the child object be declared as a member variable of its parent class in qt?
Can anyone tell me when should the child object be declared as a
member variable of its parent class in qt?
If you think you will need to call methods on (or otherwise access) the child object from other methods of parent class (as your example code does with clickBtn, referencing it from the onCheck method), then you'll want to create a member variable that is a pointer to that child object, to allow you to do so.
If, on the other hand, you will not need to access the child object outside of the method where it was created, then you can keep your parent class's definition shorter and simpler by declaring the pointer-to-the-child-object as a local variable inside the creating method only.

Why does this code create two objects while one is needed?

This is a tutorial code for Qt:
Header file:
#include <QMainWindow>
namespace Ui {
class Notepad;
}
class Notepad : public QMainWindow
{
Q_OBJECT
public:
explicit Notepad(QWidget *parent = 0);
~Notepad();
private:
Ui::Notepad *ui;
};
Source file:
#include "notepad.h"
#include "ui_notepad.h"
Notepad::Notepad(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::Notepad)
{
ui->setupUi(this);
}
Notepad::~Notepad()
{
delete ui;
}
And in main,
#include "notepad.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Notepad w;
w.show();
return a.exec();
}
So when we do Notepad w, an object is already created on the stack, and why does the code still create another object on the heap using new and assign to a member?
The one on the stack is of type Notepad, and it's the application's main window. The dynamic one is of type Ui::Notepad. That's a class automatically generated by Qt's uic tool; it contains the widgets created in UI creator as data members.
In a way, you could say that Notepad is concerned with the logic and uses an instance of Ui::Notepad to provide the GUI for it.

How can I put this qt program into one source code file

I want to have this code in one file, but can't figure out how to. I know it might not be good practice to do so but I am trying to learn qt, and would find it easier to understand the information if it were in one file.
This is the main.cpp
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
MainWindow mainWindow;
mainWindow.showMaximized();
return app.exec();
}
This is the mainwindow.cpp
#include "mainwindow.h"
#include <QCoreApplication>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
// Create the button, make "this" the parent
m_button = new QPushButton("My Button", this);
// set size and location of the button
m_button->setGeometry(QRect(QPoint(100, 100),
QSize(200, 50)));
// Connect button signal to appropriate slot
connect(m_button, SIGNAL(released()), this, SLOT(handleButton()));
}
void MainWindow::handleButton()
{
// change the text
m_button->setText("Example");
// resize button
m_button->resize(100,100);
}
this is the mainwindow.h
#define MAINWINDOW_H
#include <QMainWindow>
#include <QPushButton>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
private slots:
void handleButton();
private:
QPushButton *m_button;
};
By just copying everything in one file.
#include <QApplication>
#include <QMainWindow>
#include <QPushButton>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
private slots:
void handleButton();
private:
QPushButton *m_button;
};
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
// Create the button, make "this" the parent
m_button = new QPushButton("My Button", this);
// set size and location of the button
m_button->setGeometry(QRect(QPoint(100, 100),
QSize(200, 50)));
// Connect button signal to appropriate slot
connect(m_button, SIGNAL(released()), this, SLOT(handleButton()));
}
void MainWindow::handleButton()
{
// change the text
m_button->setText("Example");
// resize button
m_button->resize(100,100);
}
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
MainWindow mainWindow;
mainWindow.showMaximized();
return app.exec();
}
It is usually not a good idea to define new classes in same file as your main. Generally you want new classes each in their own file or you would want to put several related classes together in a seperate file. There are a tonne of resources you can google related to best practices for this. I'd suggest you spend some time reading.
But since you asked... below is how you would do it for your example. If you do not define your class above the main, the compiler will complain because it won't know what a "MainWindow" is.
#include <QApplication>
#include <QMainWindow>
#include <QPushButton>
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
private slots:
void handleButton();
private:
QPushButton *m_button;
};
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
MainWindow mainWindow;
mainWindow.showMaximized();
return app.exec();
}
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
// Create the button, make "this" the parent
m_button = new QPushButton("My Button", this);
// set size and location of the button
m_button->setGeometry(QRect(QPoint(100, 100),
QSize(200, 50)));
// Connect button signal to appropriate slot
connect(m_button, SIGNAL(released()), this, SLOT(handleButton()));
}
void MainWindow::handleButton()
{
// change the text
m_button->setText("Example");
// resize button
m_button->resize(100,100);
}
#include essentially takes the contents of whatever file you choose and copy/pastes it at that location. The compiler then starts at the top of the file and works its way down to the bottom.
Knowing that, you should be able to just copy-paste the contents of the files in the order they are included.
mainwindow.h
mainwindow.cpp
main.cpp
The short answer is don't do this, you should define a class in its own header file and #include it to the main when you want to run it in the main. This allows you to reuse the class as you see fit throughout the program, its one of the tenets of Object Oriented programming, reusable code. For example
class A
{
public:
A();
~A();
void somePublicMethod();
private:
void somePrivateMethod();
};
If you include that class in your main when you compile that class to object code(assuming you know about implementing that class in a .cpp file) then when all the object files are linked to create the program the linker basically makes one big file with all the object code included in file to be fully compiled. I suggest you read up more on compiling and linking, essentially it boils down to three phases, preprocessing, compiling and linking. Learn more about Object Oriented programming and read up why it's a bad idea to just shove them all into one file. Every class should be in its own self contained .h file(unless its a tightly coupled class) so you can include them as you see fit. Hope this helps, have fun with Qt :)