Seite 1 von 1
[gelöst] Eigene Klassen und Klassen von MainWindow benutzen
Verfasst: 19. Dezember 2009 02:07
von 24dan
Ich habe ein MainWindow mit der Klasse MainWindow.
Hier habe ich Funktion A() und B() sowie add() geschrieben.
Jetzt lagere ich für die besser Lese- und Wartbarkeit die Fkt add() in eine Eigene Klasse "Meins" aus.
So jetzt möchte ich gerne Fkt A() von MainWindow hier ansprechen:
header von Meins
Code: Alles auswählen
#include "MainWindow.h"
stuff...
MainWindow *objekt_davon;
stuff..
cpp von Meins
Code: Alles auswählen
void Meins::add()
{
int nimmDas = 9;
objekt_davon->tuMalWas(nimmDas);
}
Ist das so richtig?
Habe jetzt Probleme das ich die Fkt add() im MainWindow nicht aufrufen kann (sie funktioniert einfach nicht):
cpp von MainWindow
Code: Alles auswählen
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
stuff...
Meins *test = new Meins;
test->add()
stuff...
}
Aber aber....
leider wird die Fkt add() des Objektes test der Klasse Meins nicht ausgeführt!

Verfasst: 19. Dezember 2009 10:00
von upsala
Variablen, Funktionen und sonstige Bezeichner fangen immer mit [A-Za-z_] an.
Warum wirft dein Compiler keinen Fehler?
Verfasst: 19. Dezember 2009 12:53
von 24dan
Also meine Fkt heisst nicht 1 sondern ist nur eine Beispielbezeichnung.
Ich habe die jetzt mal umbenannt damit niemand anderes ähnliches vermutet.
1() = add()
Verfasst: 19. Dezember 2009 13:18
von upsala
Schön, dann gehen wir zum nächsten Punkt. Was meint der Debugger dazu?
Verfasst: 19. Dezember 2009 13:23
von franzf
Ich vermute mal stark, dass das nicht nur "nicht geht" sondern einfach wegsegfaulted. Dein "Meins::objekt_davon" wird nirgendwo initialisiert!
Du willst wahrscheinlich einfach nur dem Meins-Konstruktor dein MainWindow übergeben.
Kann mir das aber trotzdem nicht verkneifen:
Dieses Refactoring bringt in meinen Augen gar nichts! Das konstrukt zeigt, dass die Funktionalität eigentlich im MainWindow untergebracht werden sollte. Du erstellst ein eigenes Objekt, welches sich irgendwelche Daten zurechtbiegt, um mit denen dann auf dem MainWindow-Objekt eine Funktion aufzurufen. So wie du das jetzt vorhast, ist es nur verwirrend.
Ich würde deinem "Meins" nur die Aufgabe zukommen lassen, die Daten zu beschaffen und in einer Funktion zurück zu geben. Mit dem Ergebnis kannst du dann in MainWindow selber die Funktion aufrufen:
Code: Alles auswählen
class Meins {
public:
int funky() { return 9; }
};
MainWindow::MainWindow()
{
Meins test;
int val = test.funky();
this->tuMalWas(val);
}
Ich hoffe du verstehst worauf ich hinaus will. Dein Meins hat das MainWindow einfach nicht zu interessieren, das liefert nur die Daten.
Natürlich gibt es Fälle, in denen so ein Konstrukt durchaus Sinn macht, was du uns bisher zeigst tut das bei dir aber nicht
Kannst ja mal erklären, worauf das ganze hinaus läuft, dann kann man noch konkretere Tips geben.
Verfasst: 19. Dezember 2009 13:37
von 24dan
upsala::Debugger() ??? (Muss ich mir mal ansehen noch nicht mit gearbeitet. Komme wieder darauf zurück)
franf::Auslagern()
okay mal zum Hintergrund: "I have a plan"
1. Habe im MainWindow bisher die ftp funktionen aufgebaut.
2. Die sollen jetzt in eine eigene Klasse in einer eigenen Datei für die bessere Lese und Wartbarkeit.
3. In den Fkt. wird auch ein Statusfenster von MainWindow beschrieben
das ist die Fkt add() oder tuMalWas().
PS: Der aktuelle Quelltext aus dem MainWindow liegt hier:
http://www.qtforum.de/forum/viewtopic.php?t=10508
Da ist das schreiben ins Statusfenster aber nicht mit aufgeführt
Beispiel:
Code: Alles auswählen
/*############################################################
Name: statusFtp()
Eingang: leer
Ausgang: leer
Funktion: Informationen über die aktuelle FTP Verbindung
#############################################################*/
void MainWindow::statusFtp()
{
switch (ftp->state()){
case 0: status(tr("Keine Verbindung zum Server."));
progressDialog->hide();
break;
case 1: status(tr("Suche nach Server im Prozess."));
break;
case 2: status(tr("Server gefunden. Verbindungsaufbau im Prozess."));
break;
case 3: status(tr("Verbindung mit Server vorhanden."));
break;
case 4: status(tr("Login zum Server abgeschlossen."));
break;
case 5: status(tr("Verbindung zum Server wird abgebrochen."));
break;
}
}
@franf
also sollte ich in statusFtp() einfach einen QString mit der Meldung zurück geben? Doch die statusFtp() ist nur über einen SIGNAL SLOT Handler verbaut. Wie komme ich an die Meldung?
siehe:
Code: Alles auswählen
/*############################################################
Name: verbindenUndRunterladen()
Eingang: Dateiname die heruntergeladen werden soll
Ausgang: leer
Funktion: Update des ProzessBar
#############################################################*/
void MainWindow::verbindenUndRunterladen(QString fileName)
{
QString qs_ordner = "adler/";
if (ftp) {
ftp->abort();
ftp->deleteLater();
ftp = 0;
}
ftp = new QFtp(this);
connect(ftp,SIGNAL(stateChanged(int)),this,SLOT(statusFtp()));
ftp... (host, login, get suff...)
}
Verfasst: 19. Dezember 2009 13:43
von franzf
Statusmeldung per SIGNAL/SLOT?
Verfasst: 19. Dezember 2009 13:49
von 24dan
franzf hat geschrieben:Statusmeldung per SIGNAL/SLOT?
Eigentlich ist das nur ein workaround da ich sonst an die Meldungen im einzelnen nicht ran komme.
Ich starte ja mein connectToHost() und bekomme nur irgenwas an Meldungen mit wenn ich auf das SIGNAL (stateChanged()) reagiere.
´ne andere Möglichkeit
kenne ich noch nicht
besseren Vorschlag?[/b]
Verfasst: 26. Dezember 2009 03:50
von 24dan
franzf hat geschrieben:Statusmeldung per SIGNAL/SLOT?
Habe mir jetzt ein einfaches Signal gebaut jedoch gelingt es mir nicht das zu erhalten:
Hier mal die header von der eigenen Klasse:
Code: Alles auswählen
...
class UpdateSW : public QObject {
Q_OBJECT
public:
UpdateSW();
signals:
void done(int, QString);
public slots:
void download();
...
cpp
Code: Alles auswählen
UpdateSW::UpdateSW() : QObject()
{
}
void UpdateSW::download()
{
emit done(1, "test");
}
und hier mein Aufruf im MainWindow
Code: Alles auswählen
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ftp(0),
ui(new Ui::MainWindow)
{
UpdateSW h;
h.download();
connect(&h,SIGNAL(done(int,QString)),this,SLOT(status(int,QString)));
...
Die Funktion status() ist soweit in Ordnung habe ich mit QString als Rückgabe von UpdateSW::download() getestet.
status() ist im Header unter private slots: abgelegt.
Muss man bei emit noch gesondert was includen?
Verfasst: 26. Dezember 2009 09:28
von franzf
Was denkst du passiert mit h, wenn der MainWindow-Konstruktor durch ist?
Verfasst: 26. Dezember 2009 15:35
von 24dan
h ist dann tod !
Also in eine eigene Funktion von -> MainWindow::h_run() ?
Oder schon im header von MainWindow UpdateSW *schon_hier_h;
Dann würde ich im MainWindow:
laufen haben
Verfasst: 26. Dezember 2009 19:11
von 24dan
Okay jetzt läuft es:
Habe jetzt in MainWindow eine extra Funktion geschrieben in der ein Objekt der Klasse angelegt das connect gesetzt wird und die Funktion startet:
MainWindow
Code: Alles auswählen
void MainWindow::runa()
{
UpdateSW h;
connect(&h,SIGNAL(meldungsDienst(int,QString)) ,this,SLOT(status(int,QString)));
h.download();
}
dann hier die header von UpdateSW
Code: Alles auswählen
#ifndef UPDATE_H
#define UPDATE_H
#include <QtNetwork>
#include <QObject
class UpdateSW : public QObject {
Q_OBJECT
public:
UpdateSW();
signals:
void meldungsDienst(int, QString);
public slots:
void download();
};
#endif // UPDATE_H
und die cpp
Code: Alles auswählen
void UpdateSW::download()
{
emit meldungsDienst(1, "test");
}
Danke funktioniert jetzt mit dem Empfangen von Stausmeldungen....
