Seite 1 von 2
[gelöst] Anwendung startet nur sporadisch
Verfasst: 20. August 2009 18:35
von 101
Hallo Zusammen,
ich habe ein größeres Problem mit meiner Anwendung unter Windows.
Nach dem Instanziierung der Applikation:
wird ein mainWindow instanziiert indem wird ein Widget als MainWindow instanziiert (dieses ist mit dem Designer als UI Datei erstellt).
Dann wird die Applikation gestartet:
Das Kompilieren verläuft ohne Fehler. Die EXE kann ich aber nur sporadisch starten. Wenn die Anwendung nicht startet kommt die Fehlermeldung "Die Anweisung in 0x... verweis auf Speicher "0x0..". Mit dem Debugger komme ich bis zum Codeabschnitt im Konstruktor des Widgets:
Der Debugger wirft folgende Meldung!
Must construct a QApplication before a QPaintDevice
Kann es sein, das der Start meiner Application sporadisch durch Windows verhindert wird?
Ich komme hier mit der Fehlersuche hier nicht weiter, weil ich keinen Fehler sehe. Wenn die Anwendung erst einmal ohne Fehlermeldung gestartet ist läuft auch Alles!
Verfasst: 20. August 2009 18:37
von solarix
Wie upsala so gerne schreibt: wenn der Code geheim ist, ist auch die Lösung geheim...
Verfasst: 20. August 2009 19:01
von 101
Geheim ist hier nichts

! Ich will hier nur nicht alles zumüllen, weil der Code auf mehrere Files verteilt ist!
Mir geht es hauptsächlich um das Verständnis. Wie kann eine Anwendung mal ohne Fehler starten und dann mal wieder nicht?
Verfasst: 20. August 2009 19:30
von Christian81
Ich tippe auf eine statische Variable die auf die PaintDevice zugreift - QImage oder so. Diese wird natürlich vor main() initialisiert und fertig ist das Problem.
So lange Code aus der Anwendung rausnehmen bis es korrekt funktioniert würde ich sagen
Verfasst: 20. August 2009 19:41
von 101
Könnte es auch die Einbindung des Ui-Files im Header der Widget Klasse sein?
Code: Alles auswählen
class clSubWidget_1: public QWidget
{
Q_OBJECT
public:
clSubWidget_1(QWidget *parent = 0);
...
private:
Ui::sub_1 ui;
};
Im UI-File wird ja QPaintDevice verwendet.
Verfasst: 20. August 2009 19:44
von Christian81
Wenn Du die Klasse erst nach QApplication instanziierst was Du ja behauptest - nein.
Verfasst: 20. August 2009 19:53
von 101
ist die erste Zeile im main().

Verfasst: 20. August 2009 20:07
von solarix
Wie kann eine Anwendung mal ohne Fehler starten und dann mal wieder nicht?
Meistens weil mit Pointern was durcheinander gebracht wurde... was sich dann halt je nach Speicherinhalt anderst verhält. Daher: Code her.. wengistens die wichtigsten Abschnitte wie z.B. Konstruktoren..
ist die erste Zeile im main().
Das Spielt keine Rolle.... Statische Variabeln werden
vor main() erzeugt.. und da wir kein Code haben, wird halt geraten..
Verfasst: 20. August 2009 21:59
von 101
Hier die "Konstruktor Kette", irgend etwas läuft hier falsch:
Code: Alles auswählen
#include "main.h"
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
QApplication::setStyle("windowsxp");
//XML Config einlesen
mapConfig = new QMap<QString,QString>;
QFile file(app.applicationDirPath () + "/config.xml");
QXmlInputSource inputSource(&file);
QXmlSimpleReader xmlReader;
xmlHandler = new clXML_PARSE(mapConfig);
xmlReader.setContentHandler(xmlHandler);
xmlReader.setErrorHandler(xmlHandler);
xmlReader.parse(inputSource);
MainWindow = new clVISUAL(0,Qt::WindowStaysOnTopHint, mapConfig);
//Main Window in Bildschirmmitte zentrieren
Desktop = QApplication::desktop();
MainWindow->move((Desktop->width()-MainWindow->width())/2,(Desktop->height()-MainWindow->height())/2);
MainWindow->show();
return app.exec();
}
Konstruktor MainWindow:
Code: Alles auswählen
clVISUAL::clVISUAL(QMainWindow *parent,Qt::WindowFlags flags,QMap<QString,QString>* map):QMainWindow(parent,flags)
{
mapConfig = map;
ui.setupUi(this);
SiteStack = new QStackedWidget(this);
//StackWidget Initialisieren
SiteController = new clSITE_CONTROL(SiteStack, &ui);
}
Konstruktor SiteControl:
Code: Alles auswählen
clSITE_CONTROL::clSITE_CONTROL(QStackedWidget* SiteStackMain, Ui::VISUALClass *uiMainWindow)
{
//ui Pointer auf MainWindow
ui = uiMainWindow;
//Seiten Initialisieren
Site_Init = new clSITE_INIT(this,mConfig,0);
SiteStack->addWidget(Site_Init);
Site_Start = new clSITE_START(this,mConfig,100);
SiteStack->addWidget(Site_Start);
}
Hier als Beispiel der Konstruktor von clSITE_START:
Code: Alles auswählen
clSITE_START::clSITE_START(QWidget* parent, MAIN_Config_t* config, quint16 cycletime) : QWidget(parent)
{
ui.setupUi(this);
m_Config = config;
m_CycleTime = cycletime;
//Update Timer initialisieren
m_Timer = new QTimer();
connect(m_Timer, SIGNAL(timeout()), this, SLOT(UpdateView()));
}
Verfasst: 20. August 2009 22:04
von Christian81
Ist es so schwer so lange alles auszukommentieren bis man weiss wo es genau crasht? Dort wo Du meinst ist es definitv nicht der Fall...
Es würde sich auch lohnen einen Breakpoint auf den assert in QPaintdevice zu setzen - dazu braucht man aber ein Qt mit debug-Symbolen.
Verfasst: 20. August 2009 22:33
von NoRulez
Ich persönlich würde Pointer udgl. in der Initialisierungsliste initialisieren.
Also Beispielsweise statt:
Code: Alles auswählen
clSITE_CONTROL::clSITE_CONTROL(QStackedWidget* SiteStackMain, Ui::VISUALClass *uiMainWindow)
{
//ui Pointer auf MainWindow
ui = uiMainWindow;
.
.
.
einfach
Code: Alles auswählen
clSITE_CONTROL::clSITE_CONTROL(QStackedWidget* SiteStackMain, Ui::VISUALClass *uiMainWindow) : ui(uiMainWindow)
{
.
.
.
und falls ein Pointer nicht am Anfang initialisiert wird dann halt
Code: Alles auswählen
clSITE_CONTROL::clSITE_CONTROL(QStackedWidget* SiteStackMain, Ui::VISUALClass *uiMainWindow) : ui(0)
und das dann generell für alle Membervariablen, somit ersparst Du Dir genauso die Suche bei solchen Fehlern, gerade was Pointer angeht.
Desweiteren...ich will zwar jetzt nicht kritisieren, aber verwendest Du einen Coding-Standard? Ich persönlich finde so Klassennamen wie "clSITE_CONTROL" sehr unleserlich. Würde Dir eher empfehlen Sie beispielsweise "ClSiteControl" zu nennen, dann würde sich der Code etwas leichter lesen lassen.
Wie schon die meisten hier geschrieben haben würde auch ich gerne ein bisschen mehr Code sehen um helfen zu können.
Falls es nicht SO geheim ist, dann füge doch die Dateien bei denen Du glaubst das sie fehlerhaft sind als Attachement hinzu.
LG NoRulez
Verfasst: 20. August 2009 23:10
von 101
Assert auf QPaintDevice? Habe ich noch nie gemacht. Ich verwende Qt4.5 Free Version und als GUI QtDevelop. Im Debuger bleibe ich bei
und da bei
hängen. In der UI werden in einem Designer Plugin auch Bilder aus der Ressource angezeigt. Aber das kann ja nicht das Problem sein?
So für heute ist erst mal Schluss, habe die Nase voll
Ach ja, auskommentieren ist schlecht, da der Fehler z.B. erst beim 10. Start auftritt.
Verfasst: 20. August 2009 23:20
von NoRulez
Du könntest die Plugins mal weglassen.
Hast Du schon mal probiert kleine UnitTests für die entsprechende Module zu schreiben und vielleicht so den Fehler zu finden?
LG NoRulez
Verfasst: 21. August 2009 09:27
von solarix
hmmm.. zwei Fragen:
1. Du scheinst globale Variabeln zu haben.. wie sieht die main.h aus?
2. in clSITE_CONTROL scheinst du eine Variabel "mConfig" des Typs "MAIN_Config_t*" zu haben.. .wo wird diese Initialisiert?
Verfasst: 21. August 2009 09:28
von 101
Ich habe jetzt mein Programm auf das minimalste gekürzt, um den Fehler einzukreisen!
Hier die main.h:
Code: Alles auswählen
#ifndef __MAIN_H__
#define __MAIN_H__
#include "mainwindow.h"
#include <QtGui>
#include <QApplication>
QDesktopWidget *Desktop;
clVISUAL *MainWindow;
#endif // __MAIN_H__
hier die main.cpp:
Code: Alles auswählen
#include "main.h"
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
QApplication::setStyle("windowsxp");
//Main Window generieren und Anzeigen
Desktop = QApplication::desktop();
MainWindow = new clVISUAL(0,Qt::WindowStaysOnTopHint);
//Main Window in Bildschirmmitte zentrieren
MainWindow->move((Desktop->width()-MainWindow->width())/2,(Desktop->height()-MainWindow->height())/2);
MainWindow->show();
return app.exec();
}
hier die MainWindow.h:
Code: Alles auswählen
#ifndef __MAINWINDOW_H
#define __MAINWINDOW_H
#include <QtGui/QWidget>
#include <QMainWindow>
#include <QLayout>
#include <QDebug>
#include <QStackedWidget>
#include "ui_visual.h"
#include "site_start.h"
class clVISUAL : public QMainWindow
{
Q_OBJECT
public:
clVISUAL(QMainWindow *parent = 0,
Qt::WindowFlags flags = 0);
clSITE_START *Site_Start;
QGridLayout *MainLayout;
QStackedWidget *SiteStack;
private:
Ui::VISUALClass ui;
};
#endif // MAINWINDOW_H
hier die MainWindow.cpp:
Code: Alles auswählen
#include "rs_visual.h"
//MainWindow Konstruktor
clVISUAL::clVISUAL(QMainWindow *parent,Qt::WindowFlags flags):QMainWindow(parent,flags)
{
ui.setupUi(this);
//Klassen instanziieren
SiteStack = new QStackedWidget();
//MainLayout definieren
Site_Start = new clSITE_START;
SiteStack->addWidget(Site_Start);
MainLayout = new QGridLayout();
MainLayout->setSpacing(0);
MainLayout->setMargin(0);
MainLayout->addWidget(SiteStack);
ui.frame_2->setLayout(MainLayout);
}
Hier die Startseite.h:
Code: Alles auswählen
#ifndef __SITE_START_H__
#define __SITE_START_H__
//
#include <QtGui>
//
#include "ui_site_start.h"
//
class clSITE_START : public QWidget
{
Q_OBJECT
public:
clSITE_START(QWidget* parent=0);
private:
Ui::site_start ui;
};
#endif // __SITE_START_H__
Hier die Startseite.cpp:
Code: Alles auswählen
#include "site_start.h"
//Konstruktor
clSITE_START::clSITE_START(QWidget* parent) : QWidget(parent)
{
QString strTitle = "Hauptseite";
qDebug() << "I> Konstruktor Seite " << strTitle;
ui.setupUi(this);
}
Das ist Alles! Sobald ich mehrere Widgets per Designer in der UI enbinde, startet die Anwendung nicht mehr!