[solved] Code wird in .exe nicht ausgeführt. ?!

Alles rund um die Programmierung mit Qt
Antworten
Eric.E
Beiträge: 16
Registriert: 10. November 2011 11:06

[solved] Code wird in .exe nicht ausgeführt. ?!

Beitrag von Eric.E »

Hallo zusammen,

weiteres kleines Problem meinerseits. MSVC & Qt 4.7.0.

Ich lade in einer Funktion eine QGraphicsView in mein QMainWindow. In der QGraphicsView wird dann eine QGraphicsScene angelegt.
In Visual Studios funktioniert das alles einwandfrei.
Wenn ich das ganze per .exe ausführe komm das komische: -> Die QGraphicsView wird incl. QGraphicsScene geladen, aber alles andere in der Funktion wird nicht ausgeführt! Z.b. das Auführen von fitinView, was genau mein Problem ist, (genauso wie meine QProgressbar). Wird nämlich beim Laden einer neuen Datei nicht ausgeführt. Ich bin ehrlich gesagt ziemlich Planlos und probiere schon seit Stunden daran rum, was sich als schwer erweist, wenn in VS alles funktioniert x_x ...

Quelltext hierzu:

Funktionierendes im Quellcode vermerkt ->

Code: Alles auswählen

void mainWindow::loadFile(QString cadFilePath, QBrush CADBackgroundColor, QStringList *ptr_CADForce)
{
	if(cadFilePath.trimmed().isEmpty() == false)
	{
		/*Liste für das Loggin leeren, bevor die nächste Zeichnung geöffnet wird*/
		ptr_cadLogger->clearLists();
		
		/***********************************************************************************************************/
		/************************************ Fortschrittsdialog für das Laden einer Zeichnung ************/
		/**********************************************************************************************************/
		QProgressDialog cadProgress(this,Qt::Dialog);                  //<- wird nicht ausgeführt...
		cadProgress.setAutoClose(true);                                      //<- wird nicht ausgeführt...
		cadProgress.setLabelText("Zeichnung wird geladen...");   //<- wird nicht ausgeführt...
		cadProgress.setCancelButton(0);                                     //<- wird nicht ausgeführt...
		cadProgress.setMinimum(0);                                         //<- wird nicht ausgeführt...
		cadProgress.setMaximum(4);                                        //<- wird nicht ausgeführt...
		cadProgress.setMinimumDuration(0);                             // <- wird nicht ausgeführt...
		cadProgress.setWindowModality(Qt::WindowModal);       //<- wird nicht ausgeführt...
		
		cadProgress.setValue(1);                                               //<- wird nicht ausgeführt...
		/***********************************************************************************************************/
		/************************************ cadView-Objekt erstellen ****************************************/
		/***********************************************************************************************************/
		if(bln_gfcSet == true)
		{	
		//	ptr_CADViewArea->~cadView();
			delete ptr_CADViewArea;                                 //<- wird ausgeführt

		}
		ptr_CADViewArea = new cadView(this, cadFilePath, CADBackgroundColor, ptr_CADForce, &bln_adminOn, ptr_cadLogger);     
                                //<- wird ausgeführt.
		bln_gfcSet = true;
	
		cadProgress.setValue(2);                                          //<- wird nicht ausgeführt...
		this->setCentralWidget(ptr_CADViewArea);               //<- wird nicht ausgeführt...
		cadProgress.setValue(3);                                          //<- wird nicht ausgeführt...
		this->setCentralWidget(ptr_CADViewArea);	               //<- wird nicht ausgeführt...	
		
		/*Zeichnung auf Bildschirmgröße anpassen*/		
		cadProgress.setValue(4);                                          //<- wird nicht ausgeführt...
		Sleep(2000);                                                            //<- wird ausgeführt... !
		this->ptr_CADViewArea->fitToScreen();                     //<- wird nicht ausgeführt...

	}
}
Wie gesehen ist das interessante, dass die QGraphicsView erstellet wird, ebenso werden Sleepbefehler ausgeführt. Aber die QProgressBar sowie der Aufruf von fitToScreen (fitinview) wird nicht ausgefürt,... Zumindest sehe ich weder das Fenster, noch wird dich Zeichnung maximiert.
Über mein Menü kann ich die Funktionen aber ausführen und dann werden sie auch korrekt ausgeführt.
Zuletzt geändert von Eric.E am 17. November 2011 07:52, insgesamt 1-mal geändert.
franzf
Beiträge: 3114
Registriert: 31. Mai 2006 11:15

Re: Code wird in .exe nicht ausgeführt. ?!

Beitrag von franzf »

Ich denke, dein "Menu" öffnet einen Filedialog. Das Problem wird sein, dass der Filepath nicht stimmt - die Ursache ist nicht in "loadFile" zu suchen (da machst du eigentlich gar keine Datei auf) sondern an der aufrufenden Stelle. Liegt denn die Datei dort wo du sie erwartest? Schau vllt. auch gleich mal in die Doku -> QCoreApplication::applicationDirPath()
Eric.E
Beiträge: 16
Registriert: 10. November 2011 11:06

Re: Code wird in .exe nicht ausgeführt. ?!

Beitrag von Eric.E »

franzf hat geschrieben:Ich denke, dein "Menu" öffnet einen Filedialog. Das Problem wird sein, dass der Filepath nicht stimmt - die Ursache ist nicht in "loadFile" zu suchen (da machst du eigentlich gar keine Datei auf) sondern an der aufrufenden Stelle. Liegt denn die Datei dort wo du sie erwartest? Schau vllt. auch gleich mal in die Doku -> QCoreApplication::applicationDirPath()
Hi, danke erstmal!
Also die Datei wird dann im Konstruktor von CadGraphicsView (CadView) geladen. (Kommt dort direkt in die QGraphicsScene)
Das Problem ist: Doch der Filepath stimmt. Die Datei wird ja auch korrekt geladen und dargestellt. Das Problem ist, dass der
restliche Sourcecode nicht ausgeführt wird.
Wie gesagt: Das Bild ist da, die Sleepbefehle tun auch (getestet über hohe Werte, wo anders hält das Programm dann ja sonst nicht)

Der Filepath wird über ein Menü ausgesucht, das ist richtig, bzw. ggf. über einen übergebenen Parameter beim .exe Aufruf.
Wäre der Filepath falsch, dann würde das ganze doch auch im MSVC nicht funktionieren, oder?
franzf
Beiträge: 3114
Registriert: 31. Mai 2006 11:15

Re: Code wird in .exe nicht ausgeführt. ?!

Beitrag von franzf »

Was stellt der cadView-Konstruktor so alles an?
Deine QProgressBar lebt im Übrigen viel zu kurz, die dürfte niemals nicht sichtbar werden - liegt nur auf dem Stack und wird nach dem Scope zerstört, bevor der Funktionsfluss wieder an die EventLoop abgegeben wird, wo ein showEvent() bearbeitet werden könnte.
Wie kommst du denn überhaupt zu der Aussage, dass die Funktionen nicht ausgeführt werden? Hast du das mit dem Debugger überprüft?
Eric.E
Beiträge: 16
Registriert: 10. November 2011 11:06

Re: Code wird in .exe nicht ausgeführt. ?!

Beitrag von Eric.E »

franzf hat geschrieben:Was stellt der cadView-Konstruktor so alles an?
Deine QProgressBar lebt im Übrigen viel zu kurz, die dürfte niemals nicht sichtbar werden - liegt nur auf dem Stack und wird nach dem Scope zerstört, bevor der Funktionsfluss wieder an die EventLoop abgegeben wird, wo ein showEvent() bearbeitet werden könnte.
Wie kommst du denn überhaupt zu der Aussage, dass die Funktionen nicht ausgeführt werden? Hast du das mit dem Debugger überprüft?
Also das laden der Cad.Files dauert teilweise 3-5 Sekunden, das heißt die Progressbar wird schon noch angezeigt.

Also im Debugger habe ich es überprüft. Wie gesagt, dort wird alles ausgeführt. Es wird die ProgressBar angezeigt und dann wieder gelöscht. Es wird die Zeichnung geladen und am Ende schön in die Fenstergröße angepasst.

Wenn ich die .exe Datei in meinen externen Ordner kopiere und dort ausführe (alle .dlls verfügbar), wird eben nur die Zeichnung geladen/angezeigt, aber keine ProgressBar angezeigt, noch die Zeichnung an die Fenstergröße angepasst.
Deshalb gehe ich davon aus, dass die Funktionen garnicht ausgeführt werden, denn im VS funktioniert es ja einwandfrei (Debugger + Release),...

Ps: In Realse ausführen von MSVC funktioniert es ebenfalls. Nur eben in der .exe nicht.

ViewKonstruktor:

Code: Alles auswählen

cadView::cadView(QWidget *ptr_Parent, QString FilePath, QBrush CADBackgroundColor, QStringList *ptr_CADForce, bool *ptr_Admin, cadLog *ptr_CADLog) : QGraphicsView(ptr_Parent)
{
	setScene(new QGraphicsScene(this));
	setTransformationAnchor(AnchorUnderMouse);
	setDragMode(QGraphicsView::ScrollHandDrag);
	Transp_exists = false;

	bln_adminMode = *ptr_Admin;
	ptr_CADForces = new QStringList();
	ptr_CADForces = ptr_CADForce;
	bln_isZoomed = false;	
	ptr_CADScene = new QGraphicsScene(this);
	ptr_CADScene = scene();
	ptr_CADScene->clear();
	resetTransform();
switch(cadType)
	{
		case 4:
		case 6:
				/*Rastergrafik*/
				bln_Vector = false;
				break;
		case 1:
		case 2:
		case 3:
		case 5:
				/*Vektorgrafik*/
				bln_Vector = true;
				break;
	}
		getFileType(&cadType, &FilePath);
	if(cadType != 4 && cadType != 6)
	{
		ptr_CADDataParser = new cadParser(FilePath, cadType, ptr_Parent);
	}
	else if(cadType == 4)
	{
		ptr_CADPDFParser = new cadPDF(FilePath, ptr_Parent);
	}
	else if(cadType == 6)
	{
		loadTiff(FilePath);
	}	
		ptr_CADGenerator = new QSvgGenerator();
		ptr_CADBuffer = new QBuffer();
		ptr_CADPainter = new QPainter(ptr_CADGenerator);
		QByteArray CADBytes;
		QStringList fileName = FilePath.split(".",QString::SkipEmptyParts,Qt::CaseInsensitive);
		QString tmpSVGFile = fileName.at(0);
		tmpSVGFile.append(".svg");
		ptr_CADGenerator->setFileName(tmpSVGFile); 	
		ptr_CADGenerator->setOutputDevice(ptr_CADBuffer);
		
	if(cadType != 4 && cadType != 6)
	{	
		ptr_CADDataParser->callEnum(&CADEntities, ptr_CADLog);
		
		QByteArray tmpArray = FilePath.toLatin1();
		double d_left;
		double d_right;
		double d_top;
		double d_bottom; 
		ptr_CADDataParser->getDrawingRect(&d_left, &d_right, &d_top, &d_bottom);
		QPointF topLeft(d_left, d_top);
		QPointF bottomRight(d_right, d_bottom);
		ptr_CADViewBox = new QRectF(topLeft, bottomRight);
		/*Ansicht festlegen; Größe des SVG*/
		ptr_CADGenerator->setViewBox(*ptr_CADViewBox);
		drawOnGenerator((d_top + 1));
	}
	else if(cadType == 4)
	{
		//*PDF darstellen */	
		QImage *ptr_CADPDFImage = new QImage(ptr_CADPDFParser->createCADImg(0));		
		drawOnGenerator(ptr_CADPDFImage);	
	}
	else if(cadType == 6)
	{
		/*TIFF-Bild zeichnen*/
		drawOnGenerator(*ptr_CADTIFFImage);
	}
	CADEntities.clear();
	copyToByteArray(&CADBytes);	
	ptr_CADItem = new QGraphicsSvgItem();
	ptr_CADRender = new QSvgRenderer(CADBytes, this->ptr_CADItem);
	ptr_CADItem->setSharedRenderer(ptr_CADRender);
	ptr_CADItem->setFlags(QGraphicsItem::ItemClipsToShape);
	ptr_CADItem->setCacheMode(QGraphicsItem::NoCache);
	ptr_CADItem->setZValue(0);
	    	
	if(cadType != 4 && cadType != 6)
	{
		/*Für alle auf Schwarz*/
		setBackgroundBrush(CADBackgroundColor);
	}
	else if(cadType == 4 || cadType == 6)
	{
		/*Hintergrundfarbe für PDF's und TIFF's auf Weiß setzten*/
		setBackgroundBrush(Qt::white);
	}
	ptr_CADScene->addItem(ptr_CADItem);
	ptr_CADViewWdg = new QGLWidget(QGLFormat(QGL::NoDepthBuffer),this,0,0);
	if(cadType != 4 && cadType != 6)
	{
		
		#ifndef QT_NO_OPENGL
			setViewport(ptr_CADViewWdg);
			setRenderHint(QPainter::HighQualityAntialiasing, true);
		#endif
	}
	else
	{
		ptr_CADLabelWdg = new QLabel(this,0);
		setViewport(ptr_CADLabelWdg);
		setRenderHint(QPainter::HighQualityAntialiasing, true);
	}  
     /*QByteArray zerstören damit der Speicherverbrauch niedrig bleibt*/
     CADBytes.clear();
	 ptr_CADBuffer->~QBuffer();      
}
Eric.E
Beiträge: 16
Registriert: 10. November 2011 11:06

Re: Code wird in .exe nicht ausgeführt. ?!

Beitrag von Eric.E »

So,
habe ne Lösung gefunden, auch wenn ich dafür wahrscheinlich von Könnern verhauen werde :s

Code: Alles auswählen

	
cadProgress.setValue(4);
QApplication::processEvents(QEventLoop::AllEvents);
ptr_CADViewArea->fitToScreen();
 QCoreApplication::processEvents();
Hoffe ihr könnt mir dabei vlt noch helfen zu verstehen wieso genau das dann funktioniert und ob man
das evt schöner machen kann...

Ich gehe davon aus, dass so wie franzf es mir gesagt hat, das garnicht in die EventLoop kommt, wieso auch immer...
Da habe ich mir gedacht, die kann man doch bestimmt auch davor einfach mal aufrufen,... Naja hat geklappt...
franzf
Beiträge: 3114
Registriert: 31. Mai 2006 11:15

Re: Code wird in .exe nicht ausgeführt. ?!

Beitrag von franzf »

Das ist die einzige Lösung für dein Problem. Und ja, es liegt daran, dass du mit deiner Funktion die Queue blockierst. Es können neue Ereignisse in die Queue geschoben werden, zum Abarbeiten muss aber erstmal die EventLoop wieder zum Arbeiten kommen. processEvents() tut genau das - alles abarbeiten, was gerade drin steckt.
Die saubere Lösung wäre, das Laden des cad-files in einen eigenen Thread zu verlagern und aus diesem Thread heraus Signale zu senden, die den Progress mitteilen. Die Signale fängst du ab und passt die ProgressBar an.

Und du hast jetzt auch eines gesehen: alles was du programmierst steckt in der .exe und wird auch so aufgerufen. Wenn etwas nicht geht, liegt es meistens am Code ;)

BTW. machst du ziemlich viel unnötige Arbeit auf dem Freispeicher. Membervariablen sollten nur dann in den Freispeicher, wenn das Erstellen teuer ist die Objekte nicht immer gebraucht werden, oder wenn es eine Aggregation ist, sprich der Zeiger auf Objekte außerhalb der Instanz zeigt. Alles andere kommt in den automatischen Speicherbereich! Außerdem erstellst du viel zu viele QGraphicsScenes! (Das ist jetzt kein Speicherleck, da die über den parent() gelöscht werden - unnötig ist es trotzdem.

Und einen dicken Fehler hast du noch drinnen:

Code: Alles auswählen

cadProgress.setValue(2);
this->setCentralWidget(ptr_CADViewArea);
cadProgress.setValue(3);
this->setCentralWidget(ptr_CADViewArea);
void QMainWindow::setCentralWidget ( QWidget * widget )

Sets the given widget to be the main window's central widget.

Note: QMainWindow takes ownership of the widget pointer and deletes it at the appropriate time.
(Hatten wir hier kürzlich schonmal.)
Eric.E
Beiträge: 16
Registriert: 10. November 2011 11:06

Re: Code wird in .exe nicht ausgeführt. ?!

Beitrag von Eric.E »

franzf hat geschrieben: Und du hast jetzt auch eines gesehen: alles was du programmierst steckt in der .exe und wird auch so aufgerufen. Wenn etwas nicht geht, liegt es meistens am Code ;)
Das Problem befindet sich immer zwischen Bildschirm und Stuhl ;)
Ja, irgendwie ja schon,... Aber ich konnte es mir einfach nicht erklären :D ...
Übrigens habe ich mein anderes Problem ähnlich gelöst. Da blocke ich meine Eventqueue wohl auch.

Für den Rest den du anzumerken hast bin ich unschuldig O:) :roll:
Das war mein Vorgänger aber ich kümmer mich darum =) (Auch wenn mir nicht ganz klar ist, was daran so schlimm ist :D,... Ich wende mich mal an die Api)

Dankeschön für die Hilfe!
Antworten