Qt Error segmentation fault when trying to show window - qt

I have a class ClientWindow. I have created several instances of it and appended the their pointers to a a list. If i try to show any of the windows however, I get "Segmentation fault (core dumped)" I keep the list of windows in a class called controller.
Here is my controller header file:
#ifndef CONTROLLER_H
#define CONTROLLER_H
#include "clientwindow.h"
class Controller
{
public:
Controller();
void createClients(int num);
void showWindows();
private:
QList<ClientWindow*> clWList;
int size;
};
#endif // CONTROLLER_H
this is the cpp file:
#include "controller.h"
Controller::Controller()
{
}
void Controller::createClients(int num)
{
size = num;
for(int i = 0; i < size; i++)
{
ClientWindow cw;
clWList.append(&cw);
}
}
void Controller::showWindows()
{
for(int i = 0; i < size; i++)
{
ClientWindow* cw = clWList.at(0);
cw->show();
}
}
this is my main:
#include <QtGui/QApplication>
#include "clientwindow.h"
#include "controller.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
// ClientWindow w;
// w.show();
QString temp = argv[1];
bool ok;
int tempI = temp.toInt(&ok, 10);
Controller c;
c.createClients(tempI);
c.showWindows();
return a.exec();
}

This is where it goes wrong:
for(int i = 0; i < size; i++)
{
ClientWindow cw;
clWList.append(&cw);
}
A local variable cw is created on the stack in each iteration. It is deallocated at the end of each iteration. Meaning the data is gone. So you end up storing pointers pointing to junk.
Calling a member function of a junk typically results in crash. :) Do this instead:
for(int i = 0; i < size; i++)
{
ClientWindow * cw = new ClientWindow();
clWList.append(cw);
}
You'll have to go through the list and delete the objects after you are done with them.

Related

writeCharacters() of QXmlStreamWriter crashed when writting the content of a big file to QBuffer

The following code use writeCharacters with small buffer size to writing the content of big file, but it seems it only works when writing the content to a xml file, but writeCharacters() will crash when writting the content of a big file to QBuffer, any solution? Thanks.
env: qt opensource 4.8.7; Visual Studio 2010; Windows 10;
big file: https://1drv.ms/u/s!Ap_EAuwC9QkXijbujBQcQk4Hat_O?e=KemgUY
#include <QtCore/QCoreApplication>
#include <QFile>
#include <QXmlStreamWriter>
#include <QBuffer>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
QByteArray mContentBuffer;
QByteArray arr;
int pos, filesize;
QFile file("C:\\Work\\bigfile.xar"); //Szie: 300Mb
if(!file.open(QFile::ReadOnly))
{
return -1;
}
mContentBuffer = file.readAll();
file.close();
//QFile profile("C:\\Work\\profile.xml");
//if(!profile.open(QFile::WriteOnly|QFile::Truncate))
//{
// return -1;
//}
QBuffer buffer;
buffer.open(QBuffer::ReadWrite);
QXmlStreamWriter stream(&buffer);
stream.setAutoFormatting(true);
stream.writeStartDocument();
stream.writeStartElement("Profile");
//stream.writeTextElement("Content", mContentBuffer.toBase64());
stream.writeStartElement("Content");
pos = 0;
filesize = mContentBuffer.size();
while(pos<filesize){
arr = mContentBuffer.mid(pos, 2000000);
stream.writeCharacters(arr.toBase64());
pos+=arr.size();
}
stream.writeEndElement();
stream.writeEndElement(); // Profile
stream.writeEndDocument();
return 0;
}
Here is the goal for writing a big file into a QBuffer.
bool profileModified()
{
bool result = true;
QFile profile("C:\\Work\\profile.xml");
if(profile.exists())
{
QBuffer buffer;
buffer.open(QBuffer::ReadWrite);
QXmlStreamWriter stream(&buffer);
exportProfile(stream);
profile.open(QFile::ReadOnly);
QByteArray profileArr = profile.readAll();
buffer.seek(0);
QByteArray bufferArr = buffer.buffer();
result = (array_compare(profileArr, bufferArr) != 0);
profile.close();
}
return result;
}

QThread created in other QThread not calling destructor

I have a code:
#include <QApplication>
#include <QThread>
#include <QDebug>
class ChildThread : public QThread {
Q_OBJECT
public:
ChildThread() {
connect(this, &QThread::finished, this, &ChildThread::deleteLater);
}
~ChildThread() {
qDebug() << "~TR()";
}
protected:
void run() {
qDebug() << "RUN";
}
};
class ParentThread : public QThread {
Q_OBJECT
public:
protected:
void run() {
for (int i = 0; i < 10; i++) {
ChildThread *t = new ChildThread();
t->start();
msleep(1000);
}
}
};
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
ParentThread *t = new ParentThread();
t->start();
for (int i = 0; i < 10; i++) {
ChildThread *t = new ChildThread();
t->start();
QThread::msleep(1000);
}
return a.exec();
}
And I havnt understand, why all of the ChildThread that created in the ParentThread after reaching end of run() function not ending and desctructor of the ChildThread not called, but if I create ChildThread outside of ParentThread, deststructor of ChildThread was called?
Thank You!
The thread will not be destroyed when the run() function due to the
fact that the deleteLater() function is called when the parent (main) loop
get back the control.
Creating the ChildThread from main(), the QThread::msleep() call
give back the control to the main loop, so the destructor can be
called.

Qt application crash when trying to delete Qimage Format_RGB888

I get a "HEAP CORRUPTION DETECTED: After normal block ... CRT detected that the application wrote to memory after end of heap buffer." when variable test gets destroyed.
If I change the image size, the crash does not occur, I'm thinking it has something to do with memory alignment, but I cannot figure out what.
I am using the official Qt builds for MSVC 2017 64bit
#include <QCoreApplication>
#include <QImage>
QImage foo(int width, int height)
{
QImage retVal(width, height, QImage::Format_RGB888);
for (int i = 0; i < height; ++i) // read each line of the image
{
QRgb *lineBuf = reinterpret_cast<QRgb *>(retVal.scanLine(i));
for (int j = 0; j < width; ++j)
{
lineBuf[j] = qRgb(0,0,0);
}
}
return retVal;
}
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
{
QImage test = foo(5,5);
}
return a.exec();
}
As GM suggested in the comment above, the problem is that QRgb is a 32bit construct.
I've changed the code replacing QRgb with a custom RGB struct
struct RGB {
uint8_t r;
uint8_t g;
uint8_t b;
};
QImage foo(int width, int height)
{
QImage retVal(width, height, QImage::Format_RGB888);
for (int i = 0; i < height; ++i) // read each line of the image
{
RGB *lineBuf = reinterpret_cast<RGB *>(retVal.scanLine(i));
for (int j = 0; j < width; ++j)
{
RGB tmp;
//.... do stuff with tmp
lineBuf[j] = tmp;
}
}
return retVal;
}
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
{
QImage test = foo(5,5);
}
return a.exec();
}

Transfer serially into Arduino Uno, the text file read by Qt Creator

This is from my previous question of read the text line by line.
Based from #KubaOber answer, I can successfully read and display the content line by line in a certain time interval.
Then, I was trying to transmit the content of the text file serially into Arduino Uno using the source code available on the internet.
Here's the header code:
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QtSerialPort/QSerialPort>
#include <QSerialPortInfo>
namespace Ui {
class Widget;
}
class Widget : public QWidget
{
QSerialPort *arduino;
static const quint16 arduino_uno_vendor_id = 10755;
static const quint16 arduino_uno_product_id = 67;
QString arduino_port_name;
bool arduino_is_available;
QByteArray serialData;
QString serialBuffer;
void updateSpeedometer(QString);
Q_OBJECT
public:
explicit Widget(QWidget *parent = 0);
~Widget();
Ui::Widget *ui;
private slots:
private:
};
#endif // WIDGET_H
and here's the main.cpp :
#include <QtWidgets>
#include <QSerialPortInfo>
#include <QtSerialPort/QSerialPort>
#include "widget.h"
#include <QDebug>
bool arduino_is_available = false;
QString arduino_port_name = "";
QSerialPort *arduino = new QSerialPort;
QString serialBuffer = "";
static const quint16 arduino_uno_vendor_id = 10755;
static const quint16 arduino_uno_product_id = 67;
class PeriodicReader : public QObject {
Q_OBJECT
QTimer m_timer{this};
QFile m_file{this};
void readLine() {
if (m_file.atEnd()) {
m_timer.stop();
return;
}
QByteArray lineBaru(m_file.readLine());
emit newLine(lineBaru);
qDebug()<<lineBaru;
QString lineString(lineBaru);
qDebug()<<lineString << " converted to QString";
lineString.remove("\n");
qDebug()<<lineString;
lineString.remove(" ");
qDebug()<<lineString;
QRegExp rx("d(\\d+)");
QList<int> list;
int pos = 0;
while ((pos = rx.indexIn(lineString, pos)) != -1) {
list << rx.cap(1).toInt();
pos += rx.matchedLength();
}
qDebug()<<list;
int listi = list.at(0);
qDebug()<<"list[0] :"<<listi;// <<---THIS IS WHERE I CAN GET THE VALUE AFTER THE "d"
updateSpeedometer(lineString);
}
void updateSpeedometer(QString command)
{
if(arduino->isWritable())
{
command.remove(" ");
arduino->write(command.toStdString().c_str());
qDebug() << command.toStdString().c_str() << " is uploaded to Arduino";
}else{
qDebug()<<"Couldn't write to Serial !" ;
}
}
public:
explicit PeriodicReader(QObject * parent = {}) : QObject(parent) {
connect(&m_timer, &QTimer::timeout, this, &PeriodicReader::readLine);
}
void load(const QString & fileName) {
m_file.close(); // allow re-opening of the file
m_file.setFileName(fileName);
if (m_file.open(QFile::ReadOnly | QFile::Text)) {
readLine();
m_timer.start(1000); // <<<---------------HERE IS WHERE I WANT THE DELAY TO BE
}
}
Q_SIGNAL void newLine(const QByteArray &);
};
QString lineToString(QByteArray line)
{
while (line.endsWith('\n') || line.endsWith('\r'))
line.chop(1);
return QString::fromUtf8(line);
}
int main(int argc, char ** argv) {
qDebug()<<"Number of available ports :" <<QSerialPortInfo::availablePorts().length();
foreach(const QSerialPortInfo &serialPortInfo, QSerialPortInfo::availablePorts()){
qDebug()<<"Has Vendor ID:" << serialPortInfo.hasVendorIdentifier();
if(serialPortInfo.hasVendorIdentifier()){
qDebug()<<"Vendor ID:"<< serialPortInfo.vendorIdentifier();
}
qDebug()<<"Has Product ID:" << serialPortInfo.hasProductIdentifier();
if(serialPortInfo.hasProductIdentifier()){
qDebug()<<"Product ID:"<< serialPortInfo.productIdentifier();
}
}
foreach(const QSerialPortInfo &serialPortInfo, QSerialPortInfo::availablePorts()){
if(serialPortInfo.hasVendorIdentifier() && serialPortInfo.hasProductIdentifier()){
if(serialPortInfo.vendorIdentifier() == arduino_uno_vendor_id){
if(serialPortInfo.productIdentifier() == arduino_uno_product_id){
arduino_port_name = serialPortInfo.portName();
arduino_is_available = true;
}
}
}
}
if(arduino_is_available){
//open and configure the serialport
arduino->setPortName(arduino_port_name);
arduino->open(QSerialPort::ReadWrite);
arduino->setBaudRate(QSerialPort::Baud9600);
arduino->setDataBits(QSerialPort::Data8);
arduino->setParity(QSerialPort::NoParity);
arduino->setStopBits(QSerialPort::OneStop);
arduino->setFlowControl(QSerialPort::NoFlowControl);
//QObject::connect(arduino,SIGNAL(readyRead()),this,SLOT(readSerial()));
}else{
//show error message
qDebug()<<" Port Error, Couldn't find the Arduino' !";
// QMessageBox::warning(this, "Port Error, Couldn't find the Arduino !");
}
QApplication app{argc, argv};
QWidget window;
QVBoxLayout layout{&window};
QPushButton load{"Load"};
QPlainTextEdit edit;
layout.addWidget(&load);
layout.addWidget(&edit);
window.show();
PeriodicReader reader;
QObject::connect(&load, &QPushButton::clicked, [&]{
auto name = QFileDialog::getOpenFileName(&window);
if (!name.isEmpty()) {
edit.clear(); // allow re-opening of the file
reader.load(name);
}
});
QObject::connect(&reader, &PeriodicReader::newLine, &edit,
[&](const QByteArray & line){ edit.appendPlainText(lineToString(line)); });
return app.exec();
}
#include "main.moc"
It is from the coding of "reading text line by line" I've asked months a go which I include the arduino serial connection coding as well and hey, it worked!
It reads the text line by line and when each line is displayed in textEdit, it also transmitted to Arduino Uno.
So my request is, instead of the delay between line by line is preset at 2 seconds, can the delay duration be controlled by the content of the text file?
Let say.. the first line content inside the text file is 's200 d300' , and the 's200' is processed by arduino to generate a frequency, meanwhile 'd300' is the delay interval in milliseconds before it reads the next line and generate another frequency signal.
So,how to make Qt recognise the 'd300' and use it as the delay value?
QString str = "asa24fsesfd300kslfv0";
QTextDocument document(str);
QTextCursor d = document.find("d");
qDebug()<<d.position();
QString s = str.mid(d.position()-1,6); // How many digits can be after << d >>
int count = 0;
for (int i = 1; i < s.size(); ++i) {
QString d = s.at(i);
if(d.isEmpty()){
break;
}else{
bool ok;
int k = d.toInt(&ok);
if(ok){
count++;
}else{
break;
}
}
}
QString result = str.mid(d.position(),count);
bool ok;
int result_int = result.toInt(&ok);
if(ok){
qDebug()<< result_int;
}
result 300

To draw some points by using QImage, QWidget.update() is too slow, Is there more faster way?

I'm trying to draw a point on the window by using QImage, and update the position of this point as fast as possible(less than 1ms every update). I've wrote the code below and run it, but the result is it's too slow(about 50ms every update). I searched the bottleneck and found the cause of this slowness is calling QWidget.update() takes too long. So I figured out as long as using Widget.update() it won't be faster. So I think I need another way. Is there any faster way to do this? All of the codes and the result are the following.
result:
qimageBehaviorForStackOverflowQuestion.pro
######################################################################
# Automatically generated by qmake (3.1) Wed Mar 29 15:18:09 2017
######################################################################
TEMPLATE = app
TARGET = qimageBehaviorForStackOverflowQuestion
INCLUDEPATH += .
QT += widgets
# Input
HEADERS += qimageBehaviorForStackOverflowQuestion.h
SOURCES += qimageBehaviorForStackOverflowQuestion.cpp
qimageBehaviorForStackOverflowQuestion.h
#include <iostream>
#include <QApplication>
#include <QWidget>
#include <QTimer>
#include <QPainter>
#include <QPushButton>
#include <QImage>
#include <QTime>
class MyWidget : public QWidget {
Q_OBJECT
private:
QImage *image;
int px, py;
uchar d[100*100*4];
QTimer *timer;
QTime time;
public:
MyWidget();
void paintEvent(QPaintEvent * event);
public slots:
void doPaint();
};
qimageBehaviorForStackOverflowQuestion.cpp
#include "qimageBehaviorForStackOverflowQuestion.h"
int my_counter = 0;
MyWidget::MyWidget() : QWidget(0), px(0), py(0){
image = new QImage(d, 100, 100, QImage::Format_ARGB32);
for(int cnt = 0, a, r, g, b; cnt < 100*100*4;){
a = 255; //alpha
r = 0; //red
g = 0; //green
b = 0; //blue
d[cnt] = b; cnt++;
d[cnt] = g; cnt++;
d[cnt] = r; cnt++;
d[cnt] = a; cnt++;
}
// connect QTimer.timeout to my doPaint method
timer = new QTimer();
connect(timer, SIGNAL(timeout()), this, SLOT(doPaint()));
timer->start(1);
};
void MyWidget::doPaint(){
// manipulate the positions of the points
if(px < 100){
int cnt = 0, b = 255, g = 255, r = 255, a = 255;
d[4 * px + cnt] = b; cnt++;
d[4 * px + cnt] = g; cnt++;
d[4 * px + cnt] = r; cnt++;
d[4 * px + cnt] = a; cnt++;
px++;
}
// update the window
update();
};
void MyWidget::paintEvent(QPaintEvent * event){
QPainter painter(this);
painter.drawImage(0, 0, *image);
}
int main(int argc, char *argv[]){
QApplication app(argc, argv);
MyWidget *widget = new MyWidget();
widget->show();
return app.exec();
}
After googling couple of hours, I found more faster way. It becomes incredibly very fast(once 20FPS is now about 500FPS).What I'm using now is QGraphicsView Framework and QPixmap and QGraphicsPixmapItem. However I don't know this is the right or efficient way, if it isn't please correct me. And if you know there is more faster way please let me know. Any way I show you the code. I hope it could help someone who fight same problem.
qgraphicsSceneExample.h
#include <iostream>
#include <QApplication>
#include <QGraphicsView>
#include <QGraphicsScene>
#include <QGraphicsItem>
#include <QTimer>
#include <QPainter>
#include <QPushButton>
#include <QImage>
#include <QTime>
#include <QStyleOptionGraphicsItem>
#include <QWidget>
#include <QPixmap>
#include <QGraphicsPixmapItem>
class MyView : public QGraphicsView {
Q_OBJECT
private:
QGraphicsScene *scene;
QImage *image;
QPixmap *pixmap;
QGraphicsPixmapItem *gpixmapItem;
int px, py;
uchar d[100*100*4];
QTimer *timer;
QTime time;
public:
MyView();
//void paintEvent(QPaintEvent * event);
public slots:
void doPaint();
};
qgraphicsSceneExample.cpp
#include "qgraphicsSceneExample.h"
int my_counter = 0;
MyView::MyView() : px(0), py(0){
image = new QImage(d, 100, 100, QImage::Format_ARGB32);
for(int cnt = 0, a, r, g, b; cnt < 100*100*4;){
a = 255; //alpha
r = 0; //red
g = 0; //green
b = 0; //blue
d[cnt] = b; cnt++;
d[cnt] = g; cnt++;
d[cnt] = r; cnt++;
d[cnt] = a; cnt++;
}
// connect QTimer.timeout to my doPaint method
timer = new QTimer();
connect(timer, SIGNAL(timeout()), this, SLOT(doPaint()));
scene = new QGraphicsScene(0);
pixmap = new QPixmap(QPixmap::fromImage(*image));
gpixmapItem = scene->addPixmap(*pixmap);
this->setScene(scene);
timer->start(1);
};
void MyView::doPaint(){
// manipulate the positions of the points
if(px < 100){
int cnt = 0, b = 255, g = 255, r = 255, a = 255;
d[4 * px + cnt] = b; cnt++;
d[4 * px + cnt] = g; cnt++;
d[4 * px + cnt] = r; cnt++;
d[4 * px + cnt] = a; cnt++;
px++;
}
pixmap = new QPixmap(QPixmap::fromImage(*image));
gpixmapItem->setPixmap(*pixmap);
std::cout << my_counter++ << "\n";
};
int main(int argc, char *argv[]){
QApplication app(argc, argv);
MyView *myView = new MyView();
myView->show();
return app.exec();
}
Consider changing the incrementation of Px to more than +1, +5 for example. that will reduce the calls of doPaint() function by 5 times. and will speed up the drawing. Because your problem is that you are updating the drawing a lot, 100 times.
P.S : you should also stop the timer to stop calling doPaint() function when the drawing is finished. because it is called every 1ms. since timer.start(1) will emit timeout() signal every 1ms.
Edit:
Consider also changing the timeout that is very light (an update every 1ms <=> 1000 FPS).

Resources