Subclassing

Alles rund um die Programmierung mit Qt
joebar
Beiträge: 177
Registriert: 3. Oktober 2006 02:04

Subclassing

Beitrag von joebar »

Hallo,

ich lerne gerade Qt, daher mal eine ganz einfach Frage. Ich habe folgendes gemacht:

1. In Qt Desinger ein Projekt erstellt (test.pro)
2. UI erstellt (test.ui) bestehend aus OK und Cancel Button
3. Qt Designer ein main File generieren lassen (main.cpp)
4. qmake -o makefile test.pro aufgerufen
5. make

Mein tolles Programm laeuft so weit prima. Nun moechte ich, dass bei druecken des OK Buttons eine QMessageBox angezeigt wird. Signal und Slot anlegen sollte klar sein, aber wo muss ich nun die Methode implementieren?

Ich meine zu wissen, dass ich zwei Files brauche: Myimplementation.h und MyImplementation.cpp um eine abgeleitete Funktion zu erstellen, die Fragen nun:

1. Wie komme ich an die Files, kann mir Qt Designer ein Geruest generieren? (Sobald ich die Files habe sollte das reine C++ Coding der QMessageBox klar sein, aber das Grundgeruest ist es nicht).
2. Muss ich an dem generierten main.cpp was aendern?

Danke und Gruss,
Jochen
ChMaster
Beiträge: 252
Registriert: 23. Februar 2005 14:44
Wohnort: RP -> Alzey
Kontaktdaten:

Beitrag von ChMaster »

moin,

erstmal musst du sagen welche Qt Version du benutzt. danach könnwa dir
helfen, nur wenn du magst :P

da es gravierende unterschiede zwischen qt33x und qt41x bestehen.
ChMaster
------------ Projekte------------
DBoxFE
DMS
First4 (Plugin-Develper)
joebar
Beiträge: 177
Registriert: 3. Oktober 2006 02:04

Beitrag von joebar »

Hi,

:oops:

Noch so ein Anfaengerfehler.... Ich habe mal mit Qt 3.x gestartet, bin da aber vollkommen offen. Falls Qt 4.x Vorteile hat nehme ich auch 4.x. Wie man merkt habe ich gerade erst angefangen und habe mich mehr nach dem verfuegbaren Material an Tutorials etc. orientiert als an allem anderen.

Wie gesagt sag mir welches das "bessere" ist und das ist gekauft :roll:

Danke,
J.
caligano
Beiträge: 126
Registriert: 19. August 2006 15:33

Beitrag von caligano »

Hallo!

Qt 4 ist neuer, enthält mehr Funktionen und ist ein bisschen angenehmer. Qt 3 ist performanter, aber das sollte dir jetzt vorerst mal egal sein!
"Kaufen" musst du Qt nicht, es gibt ja die OpenSource Version:

--> ftp://ftp.trolltech.com/qt/source/qt-wi ... -mingw.exe (eigentlich sollte heute bereits die finale 4.2.0 Version released werden, vielleicht passiert das noch im Laufe des Tages)
joebar
Beiträge: 177
Registriert: 3. Oktober 2006 02:04

Beitrag von joebar »

Kaufen war bildlich gemeint :) Nutze es unter Linux. Gut also Qt4, bei dem was ich machen will spielt Performance keine Rolle. Wie mache ich es denn nun in Qt4?

Danke,
J.
joebar
Beiträge: 177
Registriert: 3. Oktober 2006 02:04

Beitrag von joebar »

Habe mir mal Qt4 installiert. Da finde ich noch nicht mal wie man ein Projekt erstellt oder das main.cpp generiert...
ChMaster
Beiträge: 252
Registriert: 23. Februar 2005 14:44
Wohnort: RP -> Alzey
Kontaktdaten:

Beitrag von ChMaster »

servus,

in qt4 ist handanlegen angesagt, also man muss die subclass einer ui
datei selbst schreiben und die main.cpp selbstverständlich auch :).


ich will mal nicht so sein und gebe dir mal ein kleines beispiel:

du hast eine datei namens guimain.ui in ihr ist zb. ein Button 'btnClose',
der uic von qt4 erzeugt dir eine ui_guimain.h die includierst du in deine
abgeleitete klasse. die so aussieht:

Bemerkung:
ich benutze grundsätzlich das komplette Modul QtCore und QtGui, da ich
schreibfaul bin :). es ist aber zu empfehlen nur das zu inkludieren was
man auch benötigt ....

MAIN : main.cpp

Code: Alles auswählen

#include <QtCore>
#include <QtGui>
#include "guimain.h"

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    GuiMain w;
    w.show();
    a.connect(&a, SIGNAL(lastWindowClosed()), &a, SLOT(quit()));
    return a.exec();
}
HEADER : guimain.h

Code: Alles auswählen

#ifndef GUIMAIN_H
#define GUIMAIN_H

#include "ui_guimain.h"

#include <QtGui>
#include <QtCore>

class GuiMain : public QWidget, public Ui::GuiMain
{
	Q_OBJECT

	public:
		GuiMain (QWidget *parent = 0);
		~GuiMain ();

	private slots:
		void slotClose();	
};

#endif // GUIMAIN_H
CPP : guimain.cpp

Code: Alles auswählen

#include "guimain.h"

#include <QtGui>
#include <QtCore>

GuiMain::GuiMain(QWidget *parent) : QWidget(parent)
{
	setupUi(this);	
	connect( btnClose, SIGNAL( clicked() ), this, SLOT( slotClose() ) );
}

GuiMain::~GuiMain()
{}

void GuiMain::slotClose()
{
	qApp->quit();
}

//...... hier die restlichen slots usw. .... :P
eine projektdatei erstellt man mit qt4 so:

qmake -project

dies erzeugt dir eine *.pro datei mit den dateien in deinem verzeichnis
wo du qmake -project ausführst ....
ChMaster
------------ Projekte------------
DBoxFE
DMS
First4 (Plugin-Develper)
joebar
Beiträge: 177
Registriert: 3. Oktober 2006 02:04

Beitrag von joebar »

Code: Alles auswählen

GuiMain::GuiMain(QWidget *parent) : QWidget(parent) 
{ 
   setupUi(this);    
   connect( btnClose, SIGNAL( clicked() ), this, SLOT( slotClose() ) ); 
} 
Du hast hier den connect string eingebaut. Ich weiss, dass ich im Designer die Signale und Slots connecten kann, wuerde das mit der Zeile connect(...) gleich setzen. Macht es im Desinger dann ueberhaupt noch Sinn die Signal/Slot Verbindungen anzulegen wenn ich sie hinterher manuel wieder einbauen muss? Ich stehe glaube ich auf dem Schlauch...

DAnke, J.
ChMaster
Beiträge: 252
Registriert: 23. Februar 2005 14:44
Wohnort: RP -> Alzey
Kontaktdaten:

Beitrag von ChMaster »

servus,

im neuen designer machen nur signal sinn die du auch brauchst.

z.B.:

du hast eine checkbox, beim anhacken soll eine liste geleert werden.
dies kannst du im designer machen. sonst kannst du keine weiteren
custom signal/slots anlegen
wie du es vom qt3 designer her kennst.



darum habe ich dir auch das kleine subclass beispiel gegeben. es wird dir
mit sicherheit einfacher fallen wenn du schon eine gui benutzt die dir die
entsprechenden header/cpp dateien erstellt. dazu eignet sich sehr gut
QDevelop, hiess früher QIde :)

diese IDE hat einen subclass generator drin, aber nur für die standart
und oder autoconnect funktionen was ich derweil für etwas schwachsinnig
halte, aber naja ;)
ChMaster
------------ Projekte------------
DBoxFE
DMS
First4 (Plugin-Develper)
joebar
Beiträge: 177
Registriert: 3. Oktober 2006 02:04

Beitrag von joebar »

Oh weia, habe den roten Faden verloren...

Ich versuche gerade zusammen zu bekommen welche Dateien ich brauche und wie ich an sie komme.

.ui File --> Via Designer
.pro File --> Via qmake -project
Die drei oben genannten --> von Hand (kann man die auch per uic generieren?)

Muss ich jetzt nicht noch das .ui File mit uic irgendwie wandeln?

Danke, J.
ChMaster
Beiträge: 252
Registriert: 23. Februar 2005 14:44
Wohnort: RP -> Alzey
Kontaktdaten:

Beitrag von ChMaster »

joebar hat geschrieben:Oh weia, habe den roten Faden verloren...
nicht schlimm, ich hab ihn noch :)
joebar hat geschrieben:Ich versuche gerade zusammen zu bekommen welche Dateien ich brauche und wie ich an sie komme.

.ui File --> Via Designer
.pro File --> Via qmake -project
Die drei oben genannten --> von Hand (kann man die auch per uic generieren?)
die 3 dateien die ich dir als beispiel gab, musst du mit der hand schreiben.
da führt kein weg drum her rum :)
joebar hat geschrieben:Muss ich jetzt nicht noch das .ui File mit uic irgendwie wandeln?
nein musst du nicht mehr, da du mit qmake -prject dir eine *pro datei
erzeugt hast. du musst nur in der shell (Windowseingabeaufforderung)
qmake und mingw32-make im ordner ausführen wo die *.pro datei leigt,
wenn du unter linux arbeitest reicht im ordner wo die *pro datei liegt
ein qmake && make aus, wohlbemerkt auch in der shell.

die *pro datei sollte so aussehen (beispiel zu den oben genannten dateien)
(ich schreibe mir grundsätzlich die pro dateien selber)

Code: Alles auswählen

TEMPLATE = app
DESTDIR = bin
DEPENDPATH += .
INCLUDEPATH += .
CONFIG += debug thread warn_on qt

FORMS += guimain.ui
HEADERS += guimain.h
SOURCES += guimain.cpp
SOURCES += main.cpp

# diese macros sind nicht unbedingt notwendig
# halten aber die lesbarkeit der projekt datei
# und sind bei grösseren projekten sehr hilfreich :)
unix{
  TARGET = guimain
  RCC_DIR = build/guimain/unix/rcc
  MOC_DIR += build/guimain/unix/moc
  OBJECTS_DIR += build/guimain/unix/obj
  UI_DIR += build/guimain/unix/ui
}

win32{
  TARGET = guimain
  RCC_DIR = build/guimain/win/rcc
  MOC_DIR += build/guimain/win/moc
  OBJECTS_DIR += build/guimain/win/obj
  UI_DIR += build/guimain/win/ui
}
ChMaster
------------ Projekte------------
DBoxFE
DMS
First4 (Plugin-Develper)
rmeeh
Beiträge: 32
Registriert: 10. September 2006 18:59
Wohnort: Geislingen
Kontaktdaten:

Beitrag von rmeeh »

Hallo zusammen,
nun fange ich mir von allen beteiligten erst mal eine dicke Beule ein......
Erstens wäre ich zum lernen bei Qt3.3 geblieben, gerade durch die rudimentärere Vorgehensweise ist meiner Meinung nach das "Verstehen" im Vordergrund. Zweitens war ja eigentlich nur nach dem Subclassing gefragt. Und genau dazu möchte ich kurz antworten:
Der Designer kann nur die Oberfläche und die dazugehörige Klasse anlegen. D.h. Du überlegst was Du in etwa willst, welche Bedienelemente (Widgets) und welche Interaktionen du mit diesen willst. Du machst also ein recht oberflächliches Klassendesign. Ok, der Designer kann Dir nun helfen mit einer xxx.ui.h eine "verbogene" Implementierung zu gestalten, aber mehr auch nicht. Soll es vernünftig weitergehen, leitest Du als nächstes eine neue Klasse ab.

>>> Grundklasse:public Designerklasse<<<

danach hast Du wieder alle Freiheitsgrade offen, inclusive der einen vernünftigen Konstruktor und Destruktor zu schaffen, ohne die eine den Grundregeln der OOP ensprechende Klasse nicht geschaffen werden sollte.
"Nach Bjarne Stroustroup sollten als minimum der parameterlose Konstruktor, Destruktor und der Copy Konstruktor ins "Leben" gerufen werden.
Stell Dir vor, Du programmierst eine Datenbankanwendung, dann kannst Du doch das gleiche Fenster zum suchen, anlegen, löschen und kopieren eines Datensatzes verwenden. Nur mit zusätzlichen oder weniger Funktionen und Funktionsumfang. Mit je einer SubClass bist Du doch besser dran als das Rad hier zig mal neu zu "zeichnen" und zu implementieren. Schon zum Löschen brauchst Du die Suchfunktion wieder um den richtigen Datensatz zu identifizieren. Also was machst Du? SubClass oder neue implementierung?

Verstehtst Du nun das Prinzip des SubClassings?

Bitte meine Vorgänger, entschldigt meine "ketzerische" Einsstellung, aber das ist meiner Meinung nach die sauberste Grundlage
Schlamperei kommt später von selber genug dazu ;-)
Liebe Grüße an alle Mitstreiter und Leser
-Ralf-
Kein Tag kommt wieder, vergessene Fehler schon....
joebar
Beiträge: 177
Registriert: 3. Oktober 2006 02:04

Beitrag von joebar »

Hi,

danke fuer die Hinweise. Ich hatte genau die Antworten bekommen die ich gesucht habe. Klar macht man als C++/Qt auch mal was unsauberes, aber ich hoffe es gibt sich mit der Zeit....

Das Problem was ich habe ist ein GUTES Tutorial zu finden. Alle Tutorials die ich gefunden habe, haben eine von zwei Schwaechen:

1. Sie arbeiten nicht mit dem Designer, und ich sehe nicht warum man alles manuell machen will
2. Sie implementieren die "echten" Funktionen im Header File, und das war dann sogar mir zu unsauber

Ich hoffe dass mit der Zeit noch ein wenig mehr Verstaendnis von Qt dazu kommt...

Danke, J.
rmeeh
Beiträge: 32
Registriert: 10. September 2006 18:59
Wohnort: Geislingen
Kontaktdaten:

Tutorial

Beitrag von rmeeh »

Hallo joebar,
nimm Dir doch das QT-Designer Manual, das liegt auf der Homepage von Trolltech. Dort sind Beispiele für die Erstellung mit dem Designer drin und wie man den Code passend erweitert. Ich fand das sehr aufschlussreich auch wenn ich einige Stellen mehr als nur einmal gelesen habe bevor mir klar wurde was da warum gemacht wird. Aber letztendlich fand ich das Designer Manual sehr hilfreich.
Gruß Ralf
Kein Tag kommt wieder, vergessene Fehler schon....
rmeeh
Beiträge: 32
Registriert: 10. September 2006 18:59
Wohnort: Geislingen
Kontaktdaten:

Beitrag von rmeeh »

Ach ja, und nochwas habe ich vergessen: Du MUSST Header und Implementierung trennen und in eigenen Dateien ablegen, also in .h und .cpp sonst bekommst Du Ärger mit dem MOC (Meta Object Compiler). Das merkst Du beizeiten wenn Du "sehr seltsame" Fehler bein übersetzen und Linken kriegst, die Du Dir absolut nicht erklären kannst. So wie nichtaufgelöste Verweise.....Das ist dann meißt ein Zeichen daß dem MOC was aufstößt. Also trenne das immer sauber, der Moc braucht nämlich die Header Datei!!!
-Ralf-
Kein Tag kommt wieder, vergessene Fehler schon....
Antworten