1. Vererbung / 2. SLOT

Alles rund um die Programmierung mit Qt
Antworten
the_immortal
Beiträge: 39
Registriert: 31. Mai 2006 21:21
Wohnort: CH

1. Vererbung / 2. SLOT

Beitrag von the_immortal »

Guten Abend

Ich bin im Moment (noch) ein ziemlicher Noob was Qt angeht und habe daher 2 Fragen:

1. Frage betrifft SignalSlots:

Kann ich wenn ich so ein SignalSlot erstelle wie z.B:

Code: Alles auswählen

QObject::connect(btnChange, SIGNAL(clicked()), mainWindow, SLOT(close()));
auch an Stelle von close() irgend ein Code hineinschreiben, oder muss es immer eine Funktion sein, welche sich in diesem Fall jetzt auf das Objekt mainWindow bezieht?


2. Frage betrifft Vererbung:

Ich möchte gerne eine Klasse MyButton erstellen welche von der Klasse QPushButton erbt. Die Klasse MyButton sollte zusätzlich eine Methode haben setText, welche den Text des PushButtons ändert.
Wäre froh wenn mir da jemand den Code kurz grob posten könnte, da ich von der Vererbung im Qt respektiv im C++ nicht viel Ahnung hab :?


Vielen Dank vorab
coffeejunky24
Beiträge: 16
Registriert: 24. April 2006 20:49
Wohnort: RhPf
Kontaktdaten:

Beitrag von coffeejunky24 »

Hallo!

Code in die connect-Zeile zu schreiben wird nicht funktionieren.

Aber du kannst in der Klasse "mainwindow" einfach einen Slot definieren und dort den code reinschreiben.

Beispiel:

in der header datei:
*schnipp*
public slots:
void resetSlot();
*schnapp*

in der cpp datei:
*schnipp*
void mainwindow::resetSlot(){
//führe diesen code aus
}
*schapp*



Zur Button vererbung.. umm ich würde eine Klasse Button schreiben. Natürlich QPushButton includen. Im Konstruktor einen String erwarten und diesen String als Button Text verwenden.
Hier ist mal Code ohne Gewähr:

button.h:

Code: Alles auswählen

#ifndef BUTTON_H
#define BUTTON_H

#include <QWidget>
 
class Button : public QWidget
{
	Q_OBJECT
	
	public:
		Button(int height, int width, char lbl[]); 
		
	public slots:
		void Click();
		
	signals:
		void clicked();
		   
}; 


#endif
button.cpp

Code: Alles auswählen

#include <QtGui>

#include "button.h"
           
Button::Button(int height, int width, char lbl[])
{     
	QPushButton *btn = new QPushButton(lbl, this);
	btn->setFont(QFont("Arial", 14, QFont::Normal));
	btn->resize(width,height);
	connect(btn, SIGNAL(clicked()), this, SLOT(Click()));
}

void Button::Click(){
	emit clicked();
}
Umm der hört dann auch auf clicked()...

Aber wie gesagt ohne Gewehr :D
the_immortal
Beiträge: 39
Registriert: 31. Mai 2006 21:21
Wohnort: CH

Beitrag von the_immortal »

Die Lösung zur ersten Frage scheint nicht wirklich zu funktionieren. Ich erhalte eine Message:

Code: Alles auswählen

./MainWindow.h:136: error: no matching function for call to `QObject::connect(QPushButton*&, const char[11], MainWindow* const, const char[14])'
F:/programs/Qt/4.1.1/include/QtCore/../../src/corelib/kernel/qobject.h:174: note: candidates are: static bool QObject::connect(const QObject*, const c
har*, const QObject*, const char*, Qt::ConnectionType)
F:/programs/Qt/4.1.1/include/QtCore/../../src/corelib/kernel/qobject.h:275: note:                 bool QObject::connect(const QObject*, const char*, c
onst char*, Qt::ConnectionType) const

Zum zweiten; warum erbst du von dem QWidget und nicht vom QPushButton? Was ist emit? Müsste in der function Click nicht etwas wie:

Code: Alles auswählen

btnChange->setText(QApplication::translate("", "Clicked", 0, QApplication::UnicodeUTF8))
sein, um den Text des QPushButton's zu ändern?
coffeejunky24
Beiträge: 16
Registriert: 24. April 2006 20:49
Wohnort: RhPf
Kontaktdaten:

Beitrag von coffeejunky24 »

Hi!

Ich weis ja nicht zu was du connectest...

connect(btnChange, SIGNAL(clicked()), mainWindow, SLOT(resetSlot()));

so müsste es im obigen Beispiel heissen...

Was emit bedeutet und einiges weiteres zu dem Thema kannst du hier nachlesen:
http://doc.trolltech.com/4.1/signalsandslots.html
Das erklärt eigentlich alles....


Im 2. Fall wird ein Widget erstellt, welches einen QPushButton mit bestimmten Parametern erstellt und das Signal clicked() aussenden kann (Verweis auf obigen Link).
Das könnte man sicher auch anders lösen und ist nur EIN Beispiel.
Der Text des Buttons wird in dieser Zeile gesetzt:
QPushButton *btn = new QPushButton(lbl, this);
analog zu dem Befehl aus der Doku:
QPushButton ( const QString & text, QWidget * parent = 0 )

http://doc.trolltech.com/4.1/qpushbutton.html

Mit ein bischen rumprobieren und lesen solltest es hinbekommen :)
Alci
Beiträge: 70
Registriert: 24. März 2006 23:34

Beitrag von Alci »

Hi,

was ich nicht verstehe ist, warum du eine setText()-Methode implementieren willst, obwohl die Klasse QPushButton bereits eine setText()-Methode hat?

Auszug aus der Doku von QPushButton:
Push buttons display a textual label, and optionally a small icon. These can be set using the constructors and changed later using setText() and setIcon()
Also wozu der Aufwand?

Zu Signal und Slot:
Wenn du folgendes hast:
QObject::connect(btnClose, SIGNAL(clicked()), mainWindow, SLOT(close()));

Dann könntest du bei SIGNAL() und SLOT() alles möglich reinschreiben, ohne das erstmal der Compiler meckert. Der Grund ist, dass SIGNAL und SLOT Macros sind, die das Übergebene in Strings umwandeln.

Also wenn z. B.
QObject::connect(btnClose, SIGNAL(clicked()), mainWindow, SLOT(gibtsNicht()))

schreibst, sagt der Compiler nichts, aber QObject::connect() würde false zurückliefern, weil der Slot gibtsNicht in der Klasse MainWindow nicht definiert wurde.

Bei der Definition eines Slots musst du folgendes beachten:
- ein Slot muss immer den Rückgabetyp void haben
- eine Klasse, in der Slots definiert werden, muss direkt oder indirekt von QObject abgeleitet sein

Wenn du ein Slot mit einem Signal verbindest, musst du außerdem darauf achten, dass die Signatur von Signal und Slot identisch ist.

Eine Definition könnte wie folgt ausschauen:

Code: Alles auswählen

//MainWindow.hpp:
class MainWindow : public QMainWindow
{
Q_OBJECT //muss angegeben werden
public slots:
void showMessage(void);
...
};

//MainWindow.cpp:
void MainWindow::showMessage(void)
{
QMessageBox mb;
mb.setText("Juhu, mein erster Slot!");
mb.exec();
}

//Main.cpp:
int main(...)
{
MainWindow* pMainWindow = new MainWindow();
QPushButton* pBtnShow = new QPushButton(pMainWindow);

QObject::connect(pBtnShow, SIGNAL(clicked()), pMainWindow, SLOT(showMessage()));
}
So, fürs erste sollte das mal reichen...
MfG, Alci.

Aktuelle Projekte:
FModPlayer: Audio-Player auf Basis von FModEx
Epp.org: C++-IDE mit MinGW-Compiler

Entwickelt wird unter anderem mit Qt 4.1.4
the_immortal
Beiträge: 39
Registriert: 31. Mai 2006 21:21
Wohnort: CH

Beitrag von the_immortal »

Ok nun ist es mir nach ein bisschen probieren gelungen ein eigener Button zu erstellen:

Code: Alles auswählen

#include <MyButton.h>
#include <QtGui/QMessageBox>

MyButton::MyButton(void)
{
   
}

void MyButton::changeText(void)
{
   QMessageBox mb;
   mb.setText("Juhu, mein erster Slot!");
   mb.exec();
   
   this.setText(QApplication::translate("", "Clicked", 0, QApplication::UnicodeUTF8));
}
Jetzt möchte ich jedoch den Text des Buttons mit der setText() Methode ändern wie kann ich denn auf die vererbte Methode zugreiffen? Mit this-> funktioniert nicht!

edit: man kann direkt setText() aufrufen habe ich soeben bemerkt :)

Wie und Wo rufe ich den Konstruktor der vererbten Klasse auf, wie z.B in Java mit super()?
Alci
Beiträge: 70
Registriert: 24. März 2006 23:34

Beitrag von Alci »

Hi,

den Konstruktor einer Oberklasse kannst du in C++ nur an einer Stelle aufrufen, und zwar im Konstruktor einer Unterklasse. Danach ist kein Aufruf des Konstruktors der Oberklasse mehr möglich. Den Konstruktor der Oberklasse rufst du in C++ über den Basisinitialisierer auf. Syntax schaut wie folgt aus:

Code: Alles auswählen

MainWindow::MainWindow(QWidget* pParent)
: QWidget(pParent)
{
}
Also bei dem jeweiligen Konstruktor der Unterklasse einfach über ": <Oberklasse>(Parameterliste)" den gewünschten Konstruktor der Oberklasse aufrufen.

C++ und Java sind doch, abgesehen von der Syntax, sehr unterschiedliche Sprachen. Vorallem was Speicherverwaltung (Java - Managed Code, C++ - Unmanaged Code) bzw. die ganze Zeiger Thematik angeht.
MfG, Alci.

Aktuelle Projekte:
FModPlayer: Audio-Player auf Basis von FModEx
Epp.org: C++-IDE mit MinGW-Compiler

Entwickelt wird unter anderem mit Qt 4.1.4
Antworten