Verbinden eines Signals mit eigenem Slot

Alles rund um die Programmierung mit Qt
SuperSonik
Beiträge: 69
Registriert: 29. Januar 2007 10:40

Verbinden eines Signals mit eigenem Slot

Beitrag von SuperSonik »

Hi Leute,
ich schaffe es nicht ein Signal eines QPushButton mit einem Slot meiner Klasse zu verbinden.
Ich hätte gerne, dass beim klicken auf diesen Button ein neues Fenster auf geht.
Das Hauptfenster habe ich im Designer erstellt und von der erzeugten Klasse meine eigene abgeleitet. Dann habe ich das zweite Fenster auch im Designer erstellt und habe wieder meine Klasse von der erstellten abgeleitet.
Jetzt möchte ich eigentlich in einem Slot des Hauptfensters den Construktor
des zweiten Fensters aufrufen.

Hier ist meine Header des Hauptfensters:

Code: Alles auswählen

#ifndef MY_MAIN_WINDOW_H_
#define MY_MAIN_WINDOW_H_
#include "my_info_window.h"
#include <QtCore>
#include <QtGui>

class my_main_window : private Ui_MainWindow
{
	Q_OBJECT
public:
	my_main_window(QMainWindow *MainWindow);
	void connect_slots(QApplication *app);
	QPushButton *new_Projekt_button;
	QPushButton *open_existing_Projekt_button;
	QPushButton *new_tga_Schema_button;
	QPushButton *back_button;
	QPushButton *copy_button;
	QPushButton *cut_button;
	QPushButton *paste_button;
	QPushButton *delete_button;
	QSpacerItem *toolbarspacer;
	QPushButton *help_button;
	QPushButton *exit_button;
	my_info_window	*info;
	QDialog dialog;
	
public slots:	
	void quit();
	void show_info_dialog(void);
};

#endif /*MY_MAIN_WINDOW_H_*/

Und hier die .cpp

Code: Alles auswählen


#include "my_main_window.h"
#include "my_info_window.h"
#include "ui_MOBILA_main_window.h"
#include <QtCore>
#include <QtGui>
#include <stdlib.h>
#include <stdio.h>

my_main_window::my_main_window(QMainWindow *MainWindow)
{
	setupUi(MainWindow);
	this->label_fortschritt->setPixmap(QPixmap(":bilder/icons/32x32/actions/button_ok.png"));
	
	//Buttons Toolbar
	new_Projekt_button = new QPushButton();
	new_Projekt_button->setIcon(QIcon(QString::fromUtf8(":bilder/icons/32x32/mimetypes/mime_empty.png")));
	new_Projekt_button->setToolTip("Neues Projekt eröffnen");

	open_existing_Projekt_button = new QPushButton();
	open_existing_Projekt_button->setIcon(QIcon(QString::fromUtf8(":bilder/icons/32x32/actions/fileopen.png")));
	open_existing_Projekt_button->setToolTip("vorhandenes Projekt öffnen");

	new_tga_Schema_button = new QPushButton();
	new_tga_Schema_button->setIcon(QIcon(QString::fromUtf8(":bilder/icons/32x32/apps/plan.svg"))); 
	new_tga_Schema_button->setToolTip("neues TGA-Schema zum Projekt hinzufügen");

	back_button = new QPushButton();
	back_button->setIcon(QIcon(QString::fromUtf8(":bilder/icons/32x32/actions/back.png")));
	back_button->setToolTip("rückgängig machen");

	copy_button = new QPushButton();
	copy_button->setIcon(QIcon(QString::fromUtf8(":bilder/icons/32x32/actions/editcopy.png")));
	copy_button->setToolTip("kopieren");

	cut_button = new QPushButton();
	cut_button->setIcon(QIcon(QString::fromUtf8(":bilder/icons/32x32/actions/editcut.png")));
	cut_button->setToolTip("ausschneiden");

	paste_button = new QPushButton();
	paste_button->setIcon(QIcon(QString::fromUtf8(":bilder/icons/32x32/actions/editpaste.png")));
	paste_button->setToolTip("einfügen");

	delete_button = new QPushButton();
	delete_button->setIcon(QIcon(QString::fromUtf8(":bilder/icons/32x32/actions/editdelete.png")));
	delete_button->setToolTip("löschen");
	
	toolbarspacer = new QSpacerItem(20, 101, QSizePolicy::Minimum, QSizePolicy::Expanding);

	help_button = new QPushButton();
	help_button->setIcon(QIcon(QString::fromUtf8(":bilder/icons/32x32/actions/help.png")));
	help_button->setToolTip("Hilfe");
	
	
	exit_button = new QPushButton();
	exit_button->setIcon(QIcon(QString::fromUtf8(":bilder/icons/32x32/actions/exit.png")));
	exit_button->setToolTip("Programm schließen");
	
	
	this->toolBar->addWidget(new_Projekt_button); 
	this->toolBar->addWidget(open_existing_Projekt_button); 
	this->toolBar->addWidget(new_tga_Schema_button);
	this->toolBar->addSeparator();
	this->toolBar->addWidget(back_button);
	this->toolBar->addWidget(copy_button);
	this->toolBar->addWidget(cut_button);
	this->toolBar->addWidget(paste_button);
	this->toolBar->addWidget(delete_button);
	this->toolBar->addSeparator(); 
	this->toolBar->addWidget(help_button);
	this->toolBar->addWidget(exit_button);
	
	//Menüs
	
	this->actionNeues_Projekt->setIcon(QIcon(QString::fromUtf8(":bilder/icons/32x32/mimetypes/mime_empty.png")));
	this->actionvorhandeneProjekte->setIcon(QIcon(QString::fromUtf8(":bilder/icons/32x32/actions/fileopen.png")));
	this->actionTGA_Schema_hinzuf_gen->setIcon(QIcon(QString::fromUtf8(":bilder/icons/32x32/apps/plan.svg")));
	this->actionSpeichern->setIcon(QIcon(QString::fromUtf8(":bilder/icons/32x32/actions/filesave.png")));
	this->actionAlle_speichern->setIcon(QIcon(QString::fromUtf8(":bilder/icons/32x32/actions/filesaveall.png")));
	this->actionSpeichern_als->setIcon(QIcon(QString::fromUtf8(":bilder/icons/32x32/actions/filesaveas.png")));
	this->actionProgramm_beenden->setIcon(QIcon(QString::fromUtf8(":bilder/icons/32x32/actions/exit.png")));
	this->actionR_ckg_ngig->setIcon(QIcon(QString::fromUtf8(":bilder/icons/32x32/actions/back.png")));
	this->actionKopieren->setIcon(QIcon(QString::fromUtf8(":bilder/icons/32x32/actions/editcopy.png")));
	this->actionAusschneiden->setIcon(QIcon(QString::fromUtf8(":bilder/icons/32x32/actions/editcut.png")));
	this->actionEinf_gen->setIcon(QIcon(QString::fromUtf8(":bilder/icons/32x32/actions/editpaste.png")));
	this->actionL_schen->setIcon(QIcon(QString::fromUtf8(":bilder/icons/32x32/actions/editdelete.png")));
	this->actionHilfe->setIcon(QIcon(QString::fromUtf8(":bilder/icons/32x32/actions/help.png")));
	this->action_ber_MOBILA->setIcon(QIcon(QString::fromUtf8(":bilder/icons/32x32/actions/messagebox_info.png")));

}

void my_main_window::connect_slots(QApplication *app)
{
	QObject::connect(this->actionProgramm_beenden, SIGNAL( triggered() ), app , SLOT( quit() ) );
	QObject::connect(this->exit_button, SIGNAL(  clicked () ), app , SLOT( quit() ) );

//////////////////////////////////////////////////////////////////////
//// Achtung : das hier klappt nicht
/////////////////////////////////////////////////////////////////////
	QObject::connect((this->help_button), SIGNAL(  clicked () ), (this) , SLOT( show_info_dialog() ) );
}

void my_main_window::show_info_dialog()
{
	printf("sdfdsfsdf");
	info = new my_info_window(); 
	
}

Was mache ich falsch?
Gruß,
SuperSonik
Christian81
Beiträge: 7319
Registriert: 26. August 2004 14:11
Wohnort: Bremen
Kontaktdaten:

Beitrag von Christian81 »

Wie soll das funktionieren wenn my_main_window nicht von QObject abgeleitet ist?

Wolltest Du evtl.
class my_main_window : private Ui_MainWindow, public QMainWindow
schreiben?

Warum erstellst Du die Hälfte mit dem Designer, erzeugst dann aber noch zig Widgets von Hand? Und dann noch so dass sie am Ende nicht gelöscht werden... :(

Wenn Du auf die Konsole schaust zeigt dir Qt zur Laufzeit auch an dass der Slot nicht gefunden wird.
MfG Christian

'Funktioniert nicht' ist keine Fehlerbeschreibung
SuperSonik
Beiträge: 69
Registriert: 29. Januar 2007 10:40

Beitrag von SuperSonik »

Eigentlich hast Du recht ich sollte alles im Designer ertellen.
Ich habe gerade erst gelernt wie man das mir den Resourcen macht und habe die Sachen dann halt in den Quellcode eingebaut.

Wie müßte ich die Elemente den anlegen damit sie gelöscht werden?

Gruß,
SuperSonik
Christian81
Beiträge: 7319
Registriert: 26. August 2004 14:11
Wohnort: Bremen
Kontaktdaten:

Beitrag von Christian81 »

Entweder im dtor selbst löschen oder besser ein Parent mit angeben. Siehe auch http://doc.trolltech.com/4.2/qobject.html#QObject
The destructor of a parent object destroys all child objects.
MfG Christian

'Funktioniert nicht' ist keine Fehlerbeschreibung
SuperSonik
Beiträge: 69
Registriert: 29. Januar 2007 10:40

Beitrag von SuperSonik »

The destructor of a parent object destroys all child objects.
Das heißt ich muss im Destructor nur mein my_main_window - Objekt
löschen?!

Vielen Dank übrigens.
Gruß,
SuperSonik
Christian81
Beiträge: 7319
Registriert: 26. August 2004 14:11
Wohnort: Bremen
Kontaktdaten:

Beitrag von Christian81 »

Da Du es übergeben bekommst würde ich sagen das ist eine nicht so gute Idee dies im dtor von my_main_window zu machen, aber im Grunde stimmt es.
Wie gesagt - die Lösung mit dem Mainwindow von aussen anstatt von QMainWindow ableiten finde ich etwas suspekt.
MfG Christian

'Funktioniert nicht' ist keine Fehlerbeschreibung
SuperSonik
Beiträge: 69
Registriert: 29. Januar 2007 10:40

Beitrag von SuperSonik »

Ich bin's nochmal.
Ich habe das mit dem ableiten von QMAinWindow
jetzt gemacht.
Beim connect - Aufruf meckert der Compiler jetzt auch nicht mehr.
Allerdings passiert auch nichts wenn ich auf den entsprechenden Button klicke. Ich habe extra ein printf rein geschrieben in den Slot , aber der String wird auch nicht ausgegeben -> das Programm springt scheinbar gar nicht in den Slot.

Mein connect - Aufruf sieht jetzt so aus:

Code: Alles auswählen

QObject::connect((this->help_button), SIGNAL(  clicked () ), (this) , SLOT( show_info_dialog() ) );
Gruß,
SuperSonik
Zuletzt geändert von SuperSonik am 3. Mai 2007 11:24, insgesamt 1-mal geändert.
Christian81
Beiträge: 7319
Registriert: 26. August 2004 14:11
Wohnort: Bremen
Kontaktdaten:

Beitrag von Christian81 »

Qt gibt Fehlermeldungen in der Konsole aus.
im pro-File
CONFIG += conole

eingeben.
Dann siehst Du was falsch läuft.
MfG Christian

'Funktioniert nicht' ist keine Fehlerbeschreibung
SuperSonik
Beiträge: 69
Registriert: 29. Januar 2007 10:40

Beitrag von SuperSonik »

Ok,

dann bekomme ich die Meldung:

Object::connect: No such slot QMainWindow::show_info_dialog()

Aber ich bin doch in der Klasse my_main_window, also ist this doch auch von diesem Typ?! Warum sucht der denn jetzt nur in QMainWindow?

SuperSonik
Christian81
Beiträge: 7319
Registriert: 26. August 2004 14:11
Wohnort: Bremen
Kontaktdaten:

Beitrag von Christian81 »

Er erkennt deine Klasse nicht -> moc wird dafür nicht ausgeführt.
Du hast zwar Q_OBJECT eingefügt, aber im pro-File den Header nicht unter
HEADERS +=
eingetragen.
MfG Christian

'Funktioniert nicht' ist keine Fehlerbeschreibung
SuperSonik
Beiträge: 69
Registriert: 29. Januar 2007 10:40

Beitrag von SuperSonik »

In die .pro Datei habe ich die Dateien schon eingetragen.
Allerdings habe ich in meine .h Datei das Makro Q_OBJECT nicht eingetragen.
-> Wenn ich das mache bekomme ich am Anfang des Constructors die Fehlermeldung:
undefined reference to `vtable for my_main_window'

Und zusätzlich noch die Fehlermeldungen:

-debug\main.o(.text$_ZN14my_main_windowD1Ev[my_main_window::
~my_main_window()]+0x46):C:/MinGW/bin/../lib/gcc/mingw32/3.4.2/../../../../include/c++/3.4.2/bits/locale_facets.tcc undefined reference to `vtable for my_main_window'
-debug\my_main_window.o In function `ZN14my_main_windowC1EP11QMainWindow':
Christian81
Beiträge: 7319
Registriert: 26. August 2004 14:11
Wohnort: Bremen
Kontaktdaten:

Beitrag von Christian81 »

nach dem Eintrag von Q_OBJECT qmake aufrufen !!!
MfG Christian

'Funktioniert nicht' ist keine Fehlerbeschreibung
SuperSonik
Beiträge: 69
Registriert: 29. Januar 2007 10:40

Beitrag von SuperSonik »

Ok,
das ist aber eine schwere Geburt. Eigentlich macht meine Entwicklungsumgebung das automatisch wenn ich die pro Datei ändere.
Ich habe qmake und make jetzt mal von Hand laufen lassen und bekomme
jetzt folgende Meldungen:

\moc_my_main_window.cpp:41: error: `staticMetaObject' is not a member of `Ui_MainWindow'
\moc_my_main_window.cpp: In member function `virtual void* my_main_window::qt_metacast(const char*)':
\moc_my_main_window.cpp:57: error: `qt_metacast' is not a member of `Ui_MainWindow'
\moc_my_main_window.cpp: In member function `virtual int my_main_window::qt_metacall(QMetaObject::Call, int, void**)':
\moc_my_main_window.cpp:62: error: `qt_metacall' is not a member of `Ui_MainWindow'

Eigentlich steht in den gemeldeten Zeile nichts.
Christian81
Beiträge: 7319
Registriert: 26. August 2004 14:11
Wohnort: Bremen
Kontaktdaten:

Beitrag von Christian81 »

Du hast ja nicht die pro-Datei sondern den Header geändert.

Lest doch bitte mal etwas die Doku:
http://doc.trolltech.com/4.2/moc.html#m ... o-be-first
MfG Christian

'Funktioniert nicht' ist keine Fehlerbeschreibung
SuperSonik
Beiträge: 69
Registriert: 29. Januar 2007 10:40

Beitrag von SuperSonik »

Ok,
so langsam wird's. Ich habe noch ein paar Fehler beseitigt.
Offensichtlich muss ich von QMainWindow zuerst ableiten:

Code: Alles auswählen

class my_main_window : public QMainWindow,private Ui_MainWindow
Jetzt erhalte ich allerdings einen Fehler vom moc:

C:/workspace/MOBILA/debug/moc_my_main_window.cpp undefined reference to `my_main_window::quit()'

Das mit der Doku lesen ist schon richtig, aber irgendwann muß man ja mal anfangen. Und bei Fehlern erstmal wissen wonach man sucht.

Gruß,
SuperSonik
Antworten