[gelöst] Anwendung startet nur sporadisch

Alles rund um die Programmierung mit Qt
101
Beiträge: 72
Registriert: 16. Januar 2008 16:28

[gelöst] Anwendung startet nur sporadisch

Beitrag von 101 »

Hallo Zusammen,

ich habe ein größeres Problem mit meiner Anwendung unter Windows.

Nach dem Instanziierung der Applikation:

Code: Alles auswählen

QApplication app(argc, argv);
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:

Code: Alles auswählen

app.exec();
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:

Code: Alles auswählen

ui.setupUi(this);
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!
Zuletzt geändert von 101 am 24. August 2009 13:17, insgesamt 1-mal geändert.
solarix
Beiträge: 1133
Registriert: 7. Juni 2007 19:25

Beitrag von solarix »

Wie upsala so gerne schreibt: wenn der Code geheim ist, ist auch die Lösung geheim...
101
Beiträge: 72
Registriert: 16. Januar 2008 16:28

Beitrag 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?
Christian81
Beiträge: 7319
Registriert: 26. August 2004 14:11
Wohnort: Bremen
Kontaktdaten:

Beitrag 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
MfG Christian

'Funktioniert nicht' ist keine Fehlerbeschreibung
101
Beiträge: 72
Registriert: 16. Januar 2008 16:28

Beitrag 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.
Christian81
Beiträge: 7319
Registriert: 26. August 2004 14:11
Wohnort: Bremen
Kontaktdaten:

Beitrag von Christian81 »

Wenn Du die Klasse erst nach QApplication instanziierst was Du ja behauptest - nein.
MfG Christian

'Funktioniert nicht' ist keine Fehlerbeschreibung
101
Beiträge: 72
Registriert: 16. Januar 2008 16:28

Beitrag von 101 »

Code: Alles auswählen

QApplication app(argc, argv);
ist die erste Zeile im main().

:?
solarix
Beiträge: 1133
Registriert: 7. Juni 2007 19:25

Beitrag 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..
101
Beiträge: 72
Registriert: 16. Januar 2008 16:28

Beitrag 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()));
}
Christian81
Beiträge: 7319
Registriert: 26. August 2004 14:11
Wohnort: Bremen
Kontaktdaten:

Beitrag 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.
MfG Christian

'Funktioniert nicht' ist keine Fehlerbeschreibung
NoRulez
Beiträge: 208
Registriert: 19. Juni 2007 15:43

Beitrag 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
101
Beiträge: 72
Registriert: 16. Januar 2008 16:28

Beitrag 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

Code: Alles auswählen

Site_Start = new clSITE_START(this,mConfig,100); 
und da bei

Code: Alles auswählen

ui.setupUi(this);
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.
NoRulez
Beiträge: 208
Registriert: 19. Juni 2007 15:43

Beitrag 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
solarix
Beiträge: 1133
Registriert: 7. Juni 2007 19:25

Beitrag 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?
101
Beiträge: 72
Registriert: 16. Januar 2008 16:28

Beitrag 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!
Antworten