Using "QWidget *QLayoutItem::widget()" throws a segment-fault (into qobjectdefs_impl.h) - qt

I'm using QTabWidget(s) inside QTabWidget tabs and when I try to get a "child" QTabWidget which is stored in the layout of a tab of the "parent" QTabWidget, I have an segment-fault error.
PS : I'm using Qt Creator v4.8.1, Qtv5.6.3 and Windows 7 64-bits OS (VM under VBox v6.0.4)
Initially, the following line throws the error
dbTablesTabWidget = static_cast<QTabWidget*>(ui->tabWidget->currentWidget()->layout()->takeAt(i)->widget());
I have tried without the "static_cast" with the following line but the error is always here
QWidget *widget = ui->tabWidget->currentWidget()->layout()->takeAt(i)->widget();
My last try (without return the QWidget pointer) with always the same "segment-fault" error.
ui->tabWidget->currentWidget()->layout()->takeAt(i)->widget();
That I don't understand is that the following line (first line in the first for loop)
QString itemClass = ui->tabWidget->currentWidget()->layout()->takeAt(i)->widget()->metaObject()->className();
works fine althought it includes the same "base code".
The segment-fault error appears in the "qobjectdefs_impl.h" file :
1 MainWindow::addRow mainwindow.cpp 298 0x403de6
2 QtPrivate::FunctorCall<QtPrivate::IndexesList<>, QtPrivate::List<>, void, void (MainWindow:: *)()>::call(void (MainWindow:: *)(), MainWindow *, void * *) qobjectdefs_impl.h 501 0x410175
3 QtPrivate::FunctionPointer<void (MainWindow:: *)()>::call<QtPrivate::List<>, void>(void (MainWindow:: *)(), MainWindow *, void * *) qobjectdefs_impl.h 520 0x4103e2
4 QtPrivate::QSlotObject<void (MainWindow:: *)(), QtPrivate::List<>, void>::impl(int, QtPrivate::QSlotObjectBase *, QObject *, void * *, bool *) qobject_impl.h 143 0x410243
5 QtPrivate::QSlotObjectBase::call qobject_impl.h 124 0x6ba5d241
6 QMetaObject::activate qobject.cpp 3715 0x6b8fc213
7 QMetaObject::activate qobject.cpp 3595 0x6b8fbc3e
8 QAbstractButton::clicked moc_qabstractbutton.cpp 307 0x9c0685
9 QAbstractButtonPrivate::emitClicked qabstractbutton.cpp 404 0x9be459
10 QAbstractButtonPrivate::click qabstractbutton.cpp 397 0x9be3f4
11 QAbstractButton::mouseReleaseEvent qabstractbutton.cpp 1002 0x9bf6f7
12 QWidget::event qwidget.cpp 8757 0x8f6881
13 QAbstractButton::event qabstractbutton.cpp 959 0x9bf56c
14 QPushButton::event qpushbutton.cpp 673 0xa55168
15 QApplicationPrivate::notify_helper qapplication.cpp 3804 0x8bf880
16 QApplication::notify qapplication.cpp 3277 0x8bd5f1
17 QCoreApplication::notifyInternal2 qcoreapplication.cpp 1015 0x6b8d37dd
18 QCoreApplication::sendSpontaneousEvent qcoreapplication.h 228 0xc2fb5d
19 QApplicationPrivate::sendMouseEvent qapplication.cpp 2773 0x8bc2cb
20 QWidgetWindow::handleMouseEvent qwidgetwindow.cpp 607 0x90f314
... <plus>
Below, an extract of the addRow Method ("custom" private slot called after the click on a QPushButton)
// var
int dbIndex = ui->tabWidget->currentIndex();
int tableIndex = 0;
QTabWidget *dbTablesTabWidget;
// Détection de l'index de l'item du layout de l'onglet de la BDD actuellement sélectionné
// -> Détection de la position du widget (jeu d'onglets des tables) dans le layout pour récupérer l'index de la table actuelle.
for (int i=0; i<ui->tabWidget->currentWidget()->layout()->count(); i++)
{
QString itemClass = ui->tabWidget->currentWidget()->layout()->takeAt(i)->widget()->metaObject()->className();
qDebug(itemClass.toLatin1());
if (itemClass == "QTabWidget")
{
qDebug("Cet élément est un QTabWidget !!!");
//*** The following line throws a segment fault ***
//dbTablesTabWidget = static_cast<QTabWidget*>(ui->tabWidget->currentWidget()->layout()->takeAt(i)->widget());
//QWidget *widget = ui->tabWidget->currentWidget()->layout()->takeAt(i)->widget();
ui->tabWidget->currentWidget()->layout()->takeAt(i)->widget();
tableIndex = dbTablesTabWidget->currentIndex();
}
}
I'm a newbie with Qt and I don't see where the segment-fault error could come from.
The compilation process is OK, please see below (french language version)
15:53:12: Configuration inchangée, étape qmake sautée.
15:53:12: Débute : "C:\Qt\Tools\mingw492_32\bin\mingw32-make.exe" -j1
C:/Qt/Tools/mingw492_32/bin/mingw32-make -f Makefile.Debug
mingw32-make[1]: Entering directory 'E:/Projects_Info_Slink/_Training/C++/QTCreatorProject/DataBaseViewerGUI/build-DataBaseViewerGUI-Desktop_Qt_5_6_3_MinGW_32bit-Debug'
mingw32-make[1]: Nothing to be done for 'first'.
mingw32-make[1]: Leaving directory 'E:/Projects_Info_Slink/_Training/C++/QTCreatorProject/DataBaseViewerGUI/build-DataBaseViewerGUI-Desktop_Qt_5_6_3_MinGW_32bit-Debug'
15:53:13: Le processus "C:\Qt\Tools\mingw492_32\bin\mingw32-make.exe" s'est terminé normalement.
15:53:13: Temps écoulé : 00:01.

Your page in tabwidget can have any widget along with a child tab widget.
To keep it simple, probably you can try the below way:
//GET YOUR CURRENT PAGE IN FIRST TAB WIDGET
QWidget *widget = ui->tabWidget->currentWidget();
//FROM THE CURRENT PAGE FIND THE CHILD TAB WIDGETS
QList<QTabWidget*> tabWidgets = widget->findChildren<QTabWidget*>();
//USE THE FOUND WIDGET FOR YOUR PURPOSE. DO SOME SAFETY CHECKS FOR LIST.
QTabWidget* requiredTabWidget = tabWidgets[0];

I have finally found the error :
I should use layout()->itemAt(i) instead layout()->takeAt(i).
It explains why the error occurs at the second time.
takeAt remove the item from the list, so during the next call, the item doesn't exist in the list.
PS : for QList object, this is at instead itemAt to get the element from the list of element.

Related

Why printing document to PDF crashes?

I am trying to run the official example for generating pdf with Qt from QtWiki but it crashes with code -1073740940. It happens at this line: QPrinter printer(QPrinter::PrinterResolution);
The printsupport is added to the project file.
I am not changing anything in the example code:
#include <QtWidgets>
#ifndef QT_NO_PRINTER
#include <QPrinter>
#endif
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
QString fileName = QFileDialog::getSaveFileName((QWidget* )0, "Export PDF", QString(), "*.pdf");
if (QFileInfo(fileName).suffix().isEmpty()) { fileName.append(".pdf"); }
QPrinter printer(QPrinter::PrinterResolution);
printer.setOutputFormat(QPrinter::PdfFormat);
printer.setPaperSize(QPrinter::A4);
printer.setOutputFileName(fileName);
QTextDocument doc;
doc.setHtml("<h1>Hello, World!</h1>\n<p>Lorem ipsum dolor sit amet, consectitur adipisci elit.</p>");
doc.setPageSize(printer.pageRect().size()); // This is necessary if you want to hide the page number
doc.print(&printer);
}
I have "Microsoft print to pdf" in devices.
What could be the reason for the crash and how to fix it?
// Added after
My setup:
Qt 5.14.1
MinGW 64 bit
Win 10 64 bit
Debugger stack trace:
1 ntdll!RtlIsNonEmptyDirectoryReparsePointAllowed 0x7ffa1b1b91b3
2 ntdll!RtlpNtMakeTemporaryKey 0x7ffa1b1c15e2
3 ntdll!RtlpNtMakeTemporaryKey 0x7ffa1b1c18ea
4 ntdll!RtlpNtMakeTemporaryKey 0x7ffa1b1ca8a9
5 ntdll!RtlGetCurrentServiceSessionId 0x7ffa1b10253a
6 ntdll!RtlGetCurrentServiceSessionId 0x7ffa1b100790
7 ntdll!RtlFreeHeap 0x7ffa1b0ffb91
8 ntdll!RtlpNtMakeTemporaryKey 0x7ffa1b1c53c9
9 ntdll!memset 0x7ffa1b175670
10 ntdll!RtlGetCurrentServiceSessionId 0x7ffa1b100790
11 ntdll!RtlFreeHeap 0x7ffa1b0ffb91
12 msvcrt!free 0x7ffa19189cfc
13 QWindowsPrintDevice::defaultPageSize() const 0x6f882e41
14 QPrintDevice::defaultPageSize() const 0x6df43efd
15 QWin32PrintEngine::QWin32PrintEngine(QPrinter::PrinterMode, QString const&) 0x6df528b2
16 QWindowsPrinterSupport::createNativePrintEngine(QPrinter::PrinterMode, QString const&) 0x6f88169a
17 QPrinterPrivate::initEngines(QPrinter::OutputFormat, QPrinterInfo const&) 0x6df4a523
18 QPrinterPrivate::init(QPrinterInfo const&, QPrinter::PrinterMode) 0x6df4a70e
19 QPrinter::QPrinter(QPrinter::PrinterMode) 0x6df4a818
20 main main.cpp 13 0x4016cc
This is not a solution but a workaround. Change your default printer. For some reason the QPrinter constructor crashes when certain printers are the system default.

Crash in QWebView

My application contains a class which inherits QWebView. The problem is that I get a crash every time I try to type something in this view! Here's my code :
void QViewSupport::setupSupport(QWidget * widget)
{
QUrl startURL = QUrl("http://www.google.fr");
load(startURL);
}
So basically whenever I try to type something in the google search bar, it crashes at the first character...
Here's the output :
ASSERTION FAILED: ICU could not open a break iterator:
U_MISSING_RESOURCE_ERROR (2)
U_SUCCESS(openStatus)
c:\work\build\qt5_workdir\w\s\qtwebkit\source\webcore\platform\text\TextBreakIteratorICU.cpp(45) : WebCore::setUpIterator
1 02426EF7
2 018F0F40
3 018F0CA0
4 018F0E1A
5 0207D7D3
6 0207CE91
7 014F1470
8 01CDBBF5
9 013EEEAC
10 013A45BE
11 01392CA7
12 013A4076
13 0134C062
14 0136166A
15 0144F19A
16 014562E3
17 014205E5
18 0141D9A6
19 017DCE6C
20 0134C82C
21 014EA80F
22 014F1525
23 013EEEAC
24 013A45BE
25 01392CA7
26 013A4076
27 0134C062
28 0136166A
29 017DCE25
30 014202C3
31 0100D627
First chance exception at 0x02426ef7 (Qt5WebKitd.dll) in myApp.exe : 0xC0000005: Access violation writing location 0xbbadbeef.
Unhandled exception à 0x02426ef7 (Qt5WebKitd.dll) in myApp.exe : 0xC0000005: Access violation writing location 0xbbadbe
Am I missing something? I searched the Internet and couldn't find something close to this problem. Thanks in advance if you have the solution!
Edit : As asked, here's the class :
class QViewSupport : public QWebView
{
Q_OBJECT
public:
QViewSupport(QWidget *parent);
~QViewSupport();
private:
void setupSupport(QWidget *Form);
};
And in the .cpp file :
#include "qviewsupport.h"
QViewSupport::QViewSupport(QWidget *parent)
: QWebView(parent)
{
setupSupport(this);
}
void QViewSupport::setupSupport(QWidget * widget)
{
QUrl startURL = QUrl("http://www.google.fr");
load(startURL);
}
QViewSupport::~QViewSupport()
{
}
Edit : The call to this function is done in Setup.cpp (see below), and pViewSupport is a private member define in the Setup class : QViewSupport* pViewSupport;.
Setup::Setup(QWidget *parent)
: QDialog(parent)
{
setupUi(this);
}
void Setup::setupUi(QWidget * widget)
{
// plenty of other things
pViewSupport = new QViewSupport(this);
// same
}
Ok, the problem came from the ICU dlls from Qt, I just replaced them and it worked.

Can't get touch event with Qt and Angstrom

My goal is to make a QT application for Technexion DevKit TDM-3730 BlizzardPack. Everything is OK, but it is impossible to click a button with a touchscreen, while with mouse it's ok.
I've tried evtest, here its output:
root#devkit:/dev/input# evtest touchscreen0
Input driver version is 1.0.1
Input device ID: bus 0x0 vendor 0x0 product 0x0 version 0x0
Input device name: "prism_st"
Supported events:
Event type 0 (Sync)
Event type 1 (Key)
Event code 330 (Touch)
Event type 3 (Absolute)
Event code 0 (X)
Value 115
Min 0
Max 1499
Event code 1 (Y)
Value 397
Min 0
Max 899
Event code 24 (Pressure)
Value 0
Min 0
Max 255
Testing ... (interrupt to exit)
Event: time 10551.906098, type 3 (Absolute), code 0 (X), value 735
Event: time 10551.906129, type 3 (Absolute), code 1 (Y), value 461
Event: time 10551.906129, type 3 (Absolute), code 24 (Pressure), value 255
Event: time 10551.906129, -------------- Report Sync ------------
Event: time 10551.915772, type 3 (Absolute), code 0 (X), value 734
Event: time 10551.915772, type 3 (Absolute), code 1 (Y), value 460
Event: time 10551.915802, -------------- Report Sync ------------
Event: time 10551.925201, type 3 (Absolute), code 0 (X), value 733
Event: time 10551.925201, type 3 (Absolute), code 1 (Y), value 459
Event: time 10551.925232, -------------- Report Sync ------------
Event: time 10551.934570, type 3 (Absolute), code 0 (X), value 732
Event: time 10551.934600, -------------- Report Sync ------------
Event: time 10551.943999, type 3 (Absolute), code 0 (X), value 730
Event: time 10551.944030, type 3 (Absolute), code 1 (Y), value 460
Event: time 10551.944030, -------------- Report Sync ------------
Event: time 10551.951659, type 3 (Absolute), code 0 (X), value 728
Event: time 10551.951690, type 3 (Absolute), code 1 (Y), value 462
Event: time 10551.951690, type 3 (Absolute), code 24 (Pressure), value 28
Event: time 10551.951690, -------------- Report Sync ------------
Event: time 10551.959014, type 3 (Absolute), code 0 (X), value 726
Event: time 10551.959044, type 3 (Absolute), code 1 (Y), value 464
Event: time 10551.959044, type 3 (Absolute), code 24 (Pressure), value 1
Event: time 10551.959044, -------------- Report Sync ------------
No matter how much I tapped there is no touch event (330).
I've made a GTK application and it's ok, but it isn't convenient at all. And it seems that touch-event processing realized inside GTK GUI. Am I right?
Here is my system parameters:
Host - Linux Mint 15, Linux version 3.8.0-19-generic, QT 5
Target - Angstrom, Linux version 2.6.37, qt4-embedded - 4.7.3-r33.1.9, tslib
Cpu - TI Sitara DM3730 # 1Ghz
DSP Core - TMS320C64x+™ # 800Mhz
TsLib environment variables are exported:
export TSLIB_TSDEVICE=/dev/input/touchscreen0
export QWS_MOUSE_PROTO=Tslib:/dev/input/touchscreen0
I'm a beginner at QT (and at Embedded systems), so I'm followwing Derek Molloy tutorial http://www.youtube.com/watch?v=kP7uvOu9hoQ on BeagleBone. But I have Technexion devkit. Beaglebone linux version is 3.2.34 and mine is 2.6.37.
Here is my test program main.cpp:
#include "mainwindow.h"
#include <QApplication>
#include <QTouchEvent>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
and here is mainwindow.cpp:
#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_pushButton_clicked()
{
ui->lineEdit->setText("DevKit");
}
And in Derek's tutorial it works ok. Could anyone tell me how I can enable qt source code to accept touch screen events?
Thank you in advance.
Egor
I think you may find this video useful in setting up your QT environment and configuring QT embedded on the BBB.
[Beaglebone: Qt Creator for C++ ARM Embedded Linux Development ]

Qt4: Unresolved timer events

A mini sample file main.cpp:
#include <iostream>
#include <QCoreApplication>
class MyApp : public QCoreApplication
{
private:
int m_idtimer;
public:
MyApp(int nargs, char* argc[]) : QCoreApplication(nargs, argc)
{
m_idtimer = startTimer(3000); // 3 segs.
}
protected:
void timerEvent(QTimerEvent* e)
{
char c = '\0';
std::cout << "timerEvent" << std::endl;
std::cin >> c;
if (c == 'q') {
killTimer(m_idtimer);
quit();
}
}
};
int main(int nargs, char* argc[])
{
MyApp app(nargs, argc);
return app.exec();
}
Extra mini Makefile:
LDFLAGS = -I/usr/include/qt4 -I/usr/include/qt4/QtCore
LDLIBS = -lQtCore
Compiling and execution:
$ make main
g++ -I/usr/include/qt4/QtCore main.cpp -lQtCore -o main
$ ./main
timerEvent
1
timerEvent
2
timerEvent
3
timerEvent
q
$
Ok and then, my question. I’ve made this sample with the purpose of testing if timer events are accumulative.
When I executing the main program, the next occurs:
the first timerEvent message is shown after 3 seconds, and timerEvent() waits a character.
I press 1 inmediatly.
3 seconds later, the second timerEvent message appear (as expected).
I wait some seconds (15 or more) and I press 2
The third message is shown immediatly (one timer event accumulated).
I press 3 immediatly.
And 3 seconds later the fourth message appear (no more timer events accumulated).
I press q and the program ends.
Question: Why aren there no more timer events accumulated? Does this behaviour depend on the platform?
PD: My Qt version is 4.8, my SO Ubuntu 13.04, and my kernel (linux) 3.8.0-19-generic. The running graphic system is Gnome 3.
Your fifteen second wait will not accumulate timer events because your timerEvent code blocks waiting for the input. Qt can't get back into its event loop until you enter the input. When it does get back to the event loop it checks the elapsed time and notices that more than 3 seconds have elapsed and so it fires off a timer event. The fact that fifteen seconds has elapsed is irrelevant.
This is the expected behaviour and will not (should not) be platform-dependent.

Qt- QNetworkReply delete operator- Runtime Crash

In my Qt application, I am using QNetworkAccessManager in a Thread so as to keep my main thread free to do its task. For every get operation that I do, I am storing the QNetworkReply* in a list and upon a response, I retrieve it from my list, delete the entry in the list and call deleteLater() on the QNetworkReply* object. However, after a couple of request/responses here is the crash i get in runtime:
The code that I used is:
void NetworkManager::responseFromServer(QNetworkReply* pReply)
{
// Retrieve the TileRequestMessage.
QImage *pImage = imageMapper.value(pReply);
// Get the bytes from the response.
QByteArray byteArray = pReply->readAll();
// Load the QImage with the data.
bool loaded = pImage->loadFromData(byteArray);
// Remove the request from book-keeping.
imageMapper.remove(mapIterator.key());
pReply->deleteLater();
return;
}
where pImage is a pointer to a object of type QImage. The Object is created in advance and its pointer mapped to a QNetworkReply* is stored in a QMap.
The error I get is:
Stopped at 0x637837aa (operator delete) in thread 1 (missing debug information).
sException at 0x637837aa, code: 0xc0000005: read access violation at: 0xffffffffcdcdcdc1,
flags=0x0
The call stack is:
0 operator delete MSVCR90D 0 0x637837aa
1 QList::node_destruct qlist.h 418 0x64071704
2 QList::free qlist.h 744 0x6407153b
3 QList::~QList qlist.h 718 0x64070b1f
4 QQueue::~QQueue qqueue.h 58 0x6407076f
5 QNetworkReplyImplPrivate::handleNotifications qnetworkreplyimpl.cpp 358 0x6406c99d
6 QNetworkReplyImpl::event qnetworkreplyimpl.cpp 868 0x6406e646
7 QApplicationPrivate::notify_helper qapplication.cpp 4445 0x6507153e
8 QApplication::notify qapplication.cpp 3845 0x6506f1ba
9 QCoreApplication::notifyInternal qcoreapplication.cpp 732 0x671c2fb1
10 QCoreApplication::sendEvent qcoreapplication.h 215 0x671c8159
11 QCoreApplicationPrivate::sendPostedEvents qcoreapplication.cpp 1373 0x671c3f0b
12 qt_internal_proc qeventdispatcher_win.cpp 506 0x67206bf9
13 IsThreadDesktopComposited USER32 0 0x77bb86ef
14 IsThreadDesktopComposited USER32 0 0x77bb8876
15 IsThreadDesktopComposited USER32 0 0x77bb89b5
16 DispatchMessageW USER32 0 0x77bb8e9c
17 QEventDispatcherWin32::processEvents qeventdispatcher_win.cpp 807 0x67207b96
18 QEventLoop::processEvents qeventloop.cpp 150 0x671c0abe
19 QEventLoop::exec qeventloop.cpp 201 0x671c0bf0
20 QThread::exec qthread.cpp 490 0x670643d6
21 DispatcherThread::run DispatcherThread.cpp 226 0x1001031a
22 QThreadPrivate::start qthread_win.cpp 317 0x6706852f
23 beginthreadex MSVCR90D 0 0x636edff3
24 beginthreadex MSVCR90D 0 0x636edf89
25 BaseThreadInitThunk kernel32 0 0x77191194
26 RtlInitializeExceptionChain ntdll 0 0x77ccb429
27 RtlInitializeExceptionChain ntdll 0 0x77ccb3fc
I am using msvc to compile my Qt code. Any heads-up on what the problem might be ??
Thanks,
Vishnu.
Without looking at your actual code and based on your error description, it could be possible that you are deleting the QNetworkReply before it has emitted the finished signal. So after the deletion when new data becomes available - QNetworkReply emits the readyRead signal which is when it would be trying to access the already deleted entry and hence the "read access violation" errors.
Just an idea:
Since you use deleteLater() you do not know when the delete will take place and thus when the pointer QNetworkReply* may be invalid in your list.
Thus, maybe try wrapping your pointer in a guared pointer (QPointer) and then just remove it from the list if it deleted/null. If it's still a valid pointer you call deleteLater();

Resources