I am using Qt5.4.3 and at some point, Qt prints out message like this
LEAK: 145 CachedResource
LEAK: 4432 WebCoreNode
I try to display a webpage on a Qt application, but whatever the webpage is, memory always leaks.
Here is the all code of project named"test"(I add the webview control in mainwindow.ui)
#test.pro
QT += core gui webkit
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets webkitwidgets multimedia multimediawidgets
TARGET = EchartDemo
TEMPLATE = app
SOURCES += main.cpp\
widget.cpp
HEADERS += widget.h
FORMS += widget.ui
INCLUDEPATH += $$PWD
MOC_DIR = temp/moc
RCC_DIR = temp/rcc
UI_DIR = temp/ui
OBJECTS_DIR = temp/obj
DESTDIR = bin
//main.cpp
#include "widget.h"
#include <QApplication>
#include <QTextCodec>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Widget w;
w.showMaximized();
return a.exec();
}
//widget.h
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
namespace Ui {
class Widget;
}
class Widget : public QWidget
{
Q_OBJECT
public:
explicit Widget(QWidget *parent = 0);
~Widget();
private:
Ui::Widget *ui;
};
#endif // WIDGET_H
//`widget.cpp`
#include "widget.h"
#include "ui_widget.h"
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
ui->webView->load(QUrl("file:///"+qApp->applicationDirPath()+"/html/hao.html"));
}
Widget::~Widget()
{
delete ui;
}
//hao.html
<meta http-equiv="Refresh" content="0; url=http://www.hao123.com/?1460255739"/><meta property="shurufa:url-navigate" content="985" />
In order to show the webpage normally, you should put the html file to the folder \build-EchartDemo-Desktop_Qt_5_4_2_MinGW_32bit-Debug\bin\html.
Of course, you can change the content of the hao.html file to whatever you like.
Why do I have these memory leaks?
This is a known bug in Qt and these "memory leaks" are only warnings in some cases. You can read more about it here : Qt Bug 40373, and also see the other bug reports mentioning those leaks.
Also, you should consider to use QWebEngineView which is much better ;) (and update to Qt5.6, but it is another story!).
Related
I am using QStateMachine framework for a device controller class. It works fine in debug mode. But, in the release mode QStateMachine::started() signal is not being emitted. A simple widget project for the problem (form is empty) is below.
Qt Version 5.14.1
Compiler : MSVC 2017, MinGW (both are 64-bit and results are same)
Test.pro
QT += core gui widgets
CONFIG += c++11
DEFINES += QT_DEPRECATED_WARNINGS
SOURCES += main.cpp mainwindow.cpp
HEADERS += mainwindow.h
FORMS += mainwindow.ui
main.cpp
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QStateMachine>
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public slots:
void stateMachineStarted();
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
private:
Ui::MainWindow *ui;
QStateMachine *stateMachine;
};
#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>
void MainWindow::stateMachineStarted()
{
qDebug() << "MainWindow::stateMachineStarted()";
}
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
qDebug() << "MainWindow::MainWindow()";
ui->setupUi(this);
stateMachine = new QStateMachine;
QState *closed = new QState;
QState *setup = new QState;
QState *opened = new QState;
QState *closing = new QState;
stateMachine->addState(closed);
stateMachine->addState(setup);
stateMachine->addState(opened);
stateMachine->addState(closing);
Q_ASSERT(connect(stateMachine, &QStateMachine::started, this, &MainWindow::stateMachineStarted));
stateMachine->setInitialState(closed);
stateMachine->start();
}
MainWindow::~MainWindow()
{
qDebug() << "MainWindow::~MainWindow()";
delete ui;
}
Application output in debug mode (I closed the form after few seconds.)
12:39:09: Starting C:\bin\build-Test-Desktop_Qt_5_14_2_MSVC2017_64bit-Debug\debug\Test.exe ...
MainWindow::MainWindow()
MainWindow::stateMachineStarted()
MainWindow::~MainWindow()
12:39:11: C:\bin\build-Test-Desktop_Qt_5_14_2_MSVC2017_64bit-Debug\debug\Test.exe exited with code 0
Application output in release mode (I closed the form after few seconds.)
12:27:51: Starting C:\bin\build-Test-Desktop_Qt_5_14_2_MSVC2017_64bit-Release\release\Test.exe ...
MainWindow::MainWindow()
MainWindow::~MainWindow()
12:27:53: C:\bin\build-Test-Desktop_Qt_5_14_2_MSVC2017_64bit-Release\release\Test.exe exited with code 0
In release mode, it is likely that the connection is not made because you wrapped it inside a Q_ASSERT macro.
See Q_ASSERT release build semantics for more informations.
I am connecting the projector to Quectel QCOM application. Now I want to skip that application and create my customized application to control the projector.
I wrote a program based on the guidelines of Quectel to switch off the projector. Following is the code. Even I used the QSerialPort code. But the projector couldn't switch off. However using the command prompt of the Quectel QCOM application, I could control the projector.
Please help me in this guys! I am stuck in this since a month.
main.cpp
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec(); //
}
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>
#include<QSerialPort>
#include<string>
#include<QtGui>
#include <QMessageBox>
using namespace std;
QSerialPort *serial;
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
}
MainWindow::~MainWindow() //
{
delete ui;
}
void MainWindow::on_pushButton_clicked()
{
QMessageBox::information(this,"Title here","Hello World");
serial = new QSerialPort(this);
serial->setPortName("COM3");
serial->setBaudRate(QSerialPort::Baud115200,QSerialPort::AllDirections);
serial->setDataBits(QSerialPort::Data8);
serial->setFlowControl(QSerialPort::NoFlowControl);
serial->setStopBits(QSerialPort::OneStop);
serial->setParity(QSerialPort::NoParity);
if(!serial->open(QIODevice::ReadWrite))
{
qDebug()<<"error: can't open com port";
}
QString command = "WT+LEDE=0\n";
QByteArray x = command.toLocal8Bit();
serial->write(x);
}
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
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_pushButton_clicked();
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
QMake project file:
#-------------------------------------------------
Project created by QtCreator 2019-11-02T10:55:21
#-------------------------------------------------
QT += core gui serialport
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = GUISerialPort
TEMPLATE = app
SOURCES += main.cpp
mainwindow.cpp
HEADERS += mainwindow.h
FORMS += mainwindow.ui
In my Application I am required to insert and remove data from tableView multiple times while application is running.After a complete cycle of Inserting and removing data from tableView memory(RAM) consumption of my application increases as checked in task Manager. After each successive cycle of insertion and deletion memory consumption keeps on Increasing.
Below is my code:
MemoryLeak.pro
#-------------------------------------------------
#
# Project created by QtCreator 2018-11-19T16:00:26
#
#-------------------------------------------------
QT += core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = MemoryLeak
TEMPLATE = app
# The following define makes your compiler emit warnings if you use
# any feature of Qt which has been marked as deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS
# You can also make your code fail to compile if you use deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
CONFIG += c++11
SOURCES += \
main.cpp \
mainwindow.cpp
HEADERS += \
mainwindow.h
FORMS += \
mainwindow.ui
# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target
Main.cpp
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.showMaximized();
return a.exec();
}
MainWindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QStandardItemModel>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = nullptr);
~MainWindow();
private:
Ui::MainWindow *ui;
QStandardItemModel *model;
public slots:
void createModel();
private slots:
void on_clearModel_clicked();
void on_displayData_clicked();
};
#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);
createModel();
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::createModel(){
model=new QStandardItemModel(this);
model->setColumnCount(3);
model->setHeaderData(0, Qt::Horizontal, tr("Name"));
model->setHeaderData(1, Qt::Horizontal, tr("Age"));
model->setHeaderData(2, Qt::Horizontal, tr("Class"));
ui->tableView->setModel(model);
ui->tableView->horizontalHeader()->setSectionResizeMode(QHeaderView::Fixed);
ui->tableView->horizontalHeader()->resizeSection(0,580);
ui->tableView->horizontalHeader()->resizeSection(1,280);
ui->tableView->horizontalHeader()->resizeSection(2,280);
ui->tableView->setAlternatingRowColors(true);
ui->tableView->setSelectionBehavior(QAbstractItemView::SelectRows);
ui->tableView->setSelectionMode(QAbstractItemView::SingleSelection);
ui->tableView->setStyleSheet("alternate-background-color:#00FF00;border: 1px solid red;");
}
void MainWindow::on_clearModel_clicked()
{
model->setRowCount(0);
}
void MainWindow::on_displayData_clicked()
{
int rowCount = 0;
QStandardItem *item;
QString value;
for(rowCount = 0; rowCount < 5000; rowCount ++){
value = QString("Person_%1").arg(rowCount);
item = new QStandardItem(QString("%0").arg(value));
model->setItem(rowCount,0,item);
// delete item;// No value is inserted in column
item = new QStandardItem(QString(" %0").arg(rowCount));
model->setItem(rowCount,1,item);
item = new QStandardItem(QString("%0").arg(2));
model->setItem(rowCount,2,item);
}
}
Memory consumption From app start:
11020 KB when app started
16144 KB when display data function Called
12812 KB when clear model called
16356 KB when display data function Called
13304 KB when clear Model Called
So Ram consumption increased by 2 MB in 2 Insert/Remove cycles.
To me it seems to be memory leak issue because memory is allocated to QStandardItem object( item = new QStandardItem(QString("%0").arg(value))) but is never freed.I tried to free the memory by calling delete item but after it a row is inserted with blank column.
What might be the possible reason for increase in memory consumption.
I try to use QwtPlot, but when i add this line to my MainWindow.cpp
QwtPlot *plot = new QwtPlot(QwtText("Demo"), this);
the application compile and link without errors, but when I try to run it I get
Program received signal SIGSEGV, Segmentation fault.
0x00007ffff514227c in ?? () from /usr/lib/libQtGui.so.4
without any backtrace. My .pro file:
INCLUDEPATH += /usr/include/qwt
CONFIG += qwt
LIBS += -lqwt
I'm using Qwt 6.0.2, Qt Creator 2.7.0 and have Qt 4.8.4 and 5.0.2 installed.
The error also occours when I create a "Qt Gui Application" (without .ui file) and just this code:
qwt-test.pro
QT += core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = qwt-test
TEMPLATE = app
INCLUDEPATH += /usr/include/qwt
CONFIG += qwt
LIBS += -lqwt
SOURCES += main.cpp\
MainWindow.cpp
HEADERS += MainWindow.hpp
main.cpp
#include "MainWindow.hpp"
#include <QApplication>
#include <QDebug>
int main(int argc, char *argv[])
{
qDebug() << "main";
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
MainWindow.hpp
#ifndef MAINWINDOW_HPP
#define MAINWINDOW_HPP
#include <QMainWindow>
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = 0);
~MainWindow();
};
#endif // MAINWINDOW_HPP
MainWindow.cpp
// MainWindow.cpp
#include "MainWindow.hpp"
#include <qwt_plot.h>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
QwtPlot *plot = new QwtPlot(QwtText("Demo"), this);
}
MainWindow::~MainWindow()
{
}
Thanks!
It was a problem with Qt Creator (or Qwt being incompatible with Qt 5), it recognized qmake as qmake for Qt 4 but it was for Qt 5. Fixing the versions in Options -> Build&Run -> Qt Versions and using Qt 4 for the project fixed the segfault.
I have created a Qt GUI application but I haven't touched anything regarding the GUI. I have modified mainwindow.cpp and the project file.
mainwindow.cpp:
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QWebPage>
#include <QWebFrame>
QWebPage page;
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
connect(page.mainFrame(), SIGNAL(loadFinished(bool)), this, SLOT(pageLoaded1(bool)));
QUrl router("http://192.168.1.1");
page.mainFrame()->load(router);
}
MainWindow::~MainWindow()
{
delete ui;
}
untitled.pro:
#-------------------------------------------------
#
# Project created by QtCreator 2013-05-01T23:48:00
#
#-------------------------------------------------
QT += core gui webkit webkitwidgets
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = untitled
TEMPLATE = app
SOURCES += main.cpp\
mainwindow.cpp
HEADERS += mainwindow.h
FORMS += mainwindow.ui
main.cpp:
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
Error:
---------------------------
Microsoft Visual C++ Debug Library
---------------------------
Debug Error!
Program: ...tled-Desktop_Qt_5_0_2_MSVC2010_32bit-Debug\debug\untitled.exe
Module: 5.0.2
File: global\qglobal.cpp
Line: 1977
ASSERT: "!"No style available without QApplication!"" in file kernel\qapplication.cpp, line 962
(Press Retry to debug the application)
---------------------------
Abort Retry Ignore
---------------------------
Extra characters are inserted here to bypass character requirement.
In main.cpp, make sure you create an application object, even if you don't use directly:
QApplication app;
// Below you can then create the window
Edit
The problem is that you are creating a QWebPage as a global object, and before the QApplication has been created. To solve the problem, make the page a member of the MainWindow class. Also make the page a pointer, otherwise you will get other problems.
i.e. in mainwindow.h:
private:
QWebPage* page;
in mainwindow.cpp:
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QWebPage>
#include <QWebFrame>
// Remove this!!
// QWebPage page;
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
// Create the page here:
page = new QWebPage(this);
connect(page.mainFrame(), SIGNAL(loadFinished(bool)), this, SLOT(pageLoaded1(bool)));
QUrl router("http://192.168.1.1");
page.mainFrame()->load(router);
}
MainWindow::~MainWindow()
{
delete ui;
}