PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : textLabel->setText funktioniert in for-schleife nicht



doitux
07-11-2004, 14:43
Hallo

Ich habe folgendes Problem:

for (int i=0;i<5;i++) {

*randint1 = rand() % 29 + 1;
*selection = char1->section( ',', *randint1, *randint1 );
cout << *selection << "\n";
textLabel1->setText( tr( *selection ) );
sleep(1);
}

innerhalb dieser for-schleife funktioniert das textLabel1->setText nur beim allerletzten Durchlauf. cout gibt 5 mal den zufallsmäßig erzeugten Buchstaben aus. Beim textLabel1 erscheint nur der letzte der 5 Buchstaben am Ende des letzten Durchlaufes.

Hat jemand eine Idee was ich da falsch mache?

queylearn.h : http://paste.phpfi.com/36046
queylearn.cpp : http://paste.phpfi.com/36045
main.cpp : http://paste.phpfi.com/36047

der obige Codeauszug befindet sich in queylearn.cpp in Zeile 110-120.

gruß
doitux

peschmae
07-11-2004, 17:22
Ich denke mal das Problem ist etwa so:
Damit etwas neu gezeichnet wird muss das Programm erst mal aus der Funktion raus und weiter den Event-Loop (mit den Paint-Events drinne) bearbeiten können.
Das geschieht aber erst nach dem letzten aufruf. Das ganze ist ja (wohl) nicht multi-threaded, d.h. es können nur Paint-Sachen ausgeführt werden wenn das Programm nicht gerade in deinem eigenen Code "feststeckt".

MfG Peschmä

doitux
07-11-2004, 17:31
mmh. dann scheint mein ganzes konzept ziemlicher müll zu sein.
das ganze sollte eigentlich mal ein programm für meinen junior werden. ein zufällig ausgesuchter buchstabe wird angezeigt und er soll diesen dann auf der tastatur finden.

hast du eventuell eine idee wie ich das ganze von grund auf richtiger angehen kann?

anda_skoa
07-11-2004, 18:01
Wenn du eine Benutzerinteraktion nach der Darstellung erwartest, also in diesem Fall das Drücken der entsprechenden Taste, hast du ohnehin keine Schleife.

Falls die Taste in einer bestimmten Zeit gedrückt werden soll, könntest du nach dem Setzen des Labeltextes einen Timer starten, der bei Ablauf einen Slot aufruft und ein neues Zeichen auswählt.

Ciao,
_

doitux
08-11-2004, 12:14
erstmal vielen dank für eure tipps. manchmal brauch ich den berühmten tritt um wieder vorwärts zu kommen. also ich hab die schleife jetzt verworfen und das ganze so realisiert:
http://paste.phpfi.com/36153
mit der schleife wollte ich u.a. auch die anzahl der durchgänge begrenzen. wenn der kleine 2 stunden lang tasten sucht wird er ja blöd, und das war ja nicht der sinn ;)
ich hab dann mal versucht ein int-pointer auf dem heap bei jedem positiven durchlauf zu inkrementieren:
http://paste.phpfi.com/36157
das funktioniert aber nicht. der *round wert spielt total verrückt. habt ihr eine idee woran das liegt?

anda_skoa
08-11-2004, 15:47
erstmal vielen dank für eure tipps. manchmal brauch ich den berühmten tritt um wieder vorwärts zu kommen. also ich hab die schleife jetzt verworfen und das ganze so realisiert:
http://paste.phpfi.com/36153

:)
Das sieht ein bischen (ganz sicher :D) so aus, als hättest du die GUI mit Designer gemacht, dann aber die von UIC generierten Dateien geändert, anstatt sauber davon abzuleiten.

Ich rate eher davon ab, es sauber zu machen erspart dir viel Ärger hinterher.



mit der schleife wollte ich u.a. auch die anzahl der durchgänge begrenzen. wenn der kleine 2 stunden lang tasten sucht wird er ja blöd, und das war ja nicht der sinn ;)

ich hab dann mal versucht ein int-pointer auf dem heap bei jedem positiven durchlauf zu inkrementieren:
http://paste.phpfi.com/36157
das funktioniert aber nicht. der *round wert spielt total verrückt. habt ihr eine idee woran das liegt?

Du hast beim Inkrement zwei Operatoren, "*" zum dereferenzieren und "++" zum inkrementieren.
Vielleicht führt er zuerst ++ aus, dann *, was in einem inkrementieren Pointer endet.

Ich würde eher dazu raten, die ganzen Pointer zu vergessen, da sie nur unnötig die Komplexität erhöhen. "round" einfach ganz normal in als Member der Klasse, "selection" und "char1" genauso.

Ciao,
_

doitux
08-11-2004, 17:38
danke für den pointer-tip. hab jetzt variablen raus gemacht. ich hatte irgendwie gedacht dass ich die variablen dann bei jeder funktion mit überladen müsste und wollte mir diesen stress ersparen. aber scheinbar geht das auch so.

das mit dem designer stimmt. ich hab diese ui-datei mit uci nach *.h und *.cpp umgewandelt. ich wusste gar nicht dass man das auch anders machen kann. muss man dann die funkionen und die zusätzlichen variablen und pointer noch in eine extra *.h und *.cpp datei schreiben? und muss man die ui-datei dann includen?

anda_skoa
08-11-2004, 18:28
Übliches Vorgehen ist dies:

- Widget im Designer erstellen
- Header und CPP Datei erstellen für eine Klasse erstellen, die von der Designer/UIC generierten ableitet.

Sagen wir, ich möchte ein Widget im Designer erstellen und layouten und es dann im Programm mit dem Namen MyWidget benutzen.
Dann gebe ich im Designer beim Formnamen, der ja zum Klassennamen wird, MyWidgetBase an, um anzudeuten, dass es die Basisklasse für eine andere Klasse wird.
Dann erzeuge ich zwei Dateien, mywidget.h und mywidget.cpp, wobei in mywidget.h in etwa folgendes steht



#ifndef MYWIDGET_H
#define MYWIDGET_H

#include "mywidgetbase.h"

class MyWidget : public MyWidgetBase
{
Q_OBJECT
public:
// Kontruktoren, Methoden, etc
};

#endif


Die Datei mywidgetbase.h wird ja von uic generiert, unter der Annahme dass du ein Buildsystem wie zB qmake verwendest, brauchst du dich um diesen Schritt nicht weiter zu kümmern.

Zu der Sache mit den Pointern: einer der Vorteile der objektorientierten Programmierung ist eben, dass jeder Instanz einer Klasse ein Satz von Eigenschaften zugeordnet ist, der über die Methoden der Klasse manipuliert wird.
Diese Variablen der Instanz sind aus Sicht der Klassenmethoden praktisch "global", müssen also nicht als Parameter übergeben werden.

Ciao,
_

doitux
08-11-2004, 21:25
herzlichsten dank für die umfangreichen erklärungen. ich weiß gar nicht wie ich mich bedanken soll. wenn du zufällig in rostock ;) wohnst lad ich dich zu einem abend in einer kneipe deiner wahl ein.
ich werd das jetzt mal ausprobieren mit dem designer und den *.ui usw.

nochmal vielen vielen dank

gruß
doitux

doitux
09-11-2004, 07:49
hallo anda_skoa

wenn ich dich nicht zu sehr nerve, hätte ich da nochmal eine frage zur implementierung.
wenn ich nur mit der queybase.ui ein qmake mache dann kommt dabei queybase.h und queybase.cpp heraus.
dann hab ich aus queybase.h und queylearn.cpp alles rausgenommen was in queybase.h und queybase.cpp drin ist.

meine queylearn.h sieht in so aus


#ifndef QUEYLEARN_H
#define QUEYLEARN_H

#include "queybase.h"
#include <iostream.h>
#include <qtimer.h>
#include <qstring.h>
#include <time.h>

class QString;

class Queylearn : public queybase
{
Q_OBJECT

public:
Queylearn( QWidget* parent = 0, const char* name = 0, bool modal = FALSE, WFlags fl = 0 );
~Queylearn();

QString* char1;

public slots:

void startGame();
void charCheck(const QString&);

private:
int round;
int randint1;
QString selection;

private slots:

void nextRandom();

protected:

protected slots:

};

#endif // QUEYLEARN_H


das Problem ist jetzt, das qmake mit queybase.ui, queylearn.h, queylearn.cpp und main.cpp in einem verzeichnis zwar die datei queybase.h aber keine queybase.cpp mehr erstellt. muss ich diese implementierung doch auch in der queylearn.cpp realisieren? in der queybase.cpp waren vorher auch alle qt-header includes drin die jetzt fehlen.

hier ist noch der Anfang der queylearn.cpp:


#include "queylearn.h"

Queylearn::Queylearn( QWidget* parent, const char* name, bool modal, WFlags fl )
: queybase( parent, name, modal, fl )

ist das richtig mit dem


: queybase( parent, name, modal, fl ) ?

vorher stand da:


: QDialog( parent, name, modal, fl )

anda_skoa
13-11-2004, 17:44
das Problem ist jetzt, das qmake mit queybase.ui, queylearn.h, queylearn.cpp und main.cpp in einem verzeichnis zwar die datei queybase.h aber keine queybase.cpp mehr erstellt. muss ich diese implementierung doch auch in der queylearn.cpp realisieren? in der queybase.cpp waren vorher auch alle qt-header includes drin die jetzt fehlen.

Ansich musst du da nichts mehr zusätzlich machen.
Wie sieht denn deine .pro Datei aus?


ist das richtig mit dem


: queybase( parent, name, modal, fl ) ?

vorher stand da:


: QDialog( parent, name, modal, fl )

Ja, das passt schon, die Initialisierung der Basisklasse QDialog steht ja jetzt in queybase.cpp

Ciao,
_

doitux
14-11-2004, 00:21
ich hab mir nochmal dein tutorial angeschaut. dann hab ich mal das uics-verzeichnis erstellt, und die *.pro entsprechend angepasst. mit make uicables hat er mir auch die queylearnbase.cpp erstellt.
dann hab ich festgestellt das der fehler schon früher passierte nämlich in der queylearn.h so dass er gar nicht mehr zum erstellen der queylearnbase.cpp kam. jetzt funktioniert das so wie es soll. also nochmal danke für deine hilfe und vorallem auch für dein turorial.