Seite 1 von 2

Verbinden eines Signals mit eigenem Slot

Verfasst: 2. Mai 2007 16:31
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

Verfasst: 2. Mai 2007 17:42
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.

Verfasst: 3. Mai 2007 08:35
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

Verfasst: 3. Mai 2007 08:41
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.

Verfasst: 3. Mai 2007 10:43
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

Verfasst: 3. Mai 2007 10:47
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.

Verfasst: 3. Mai 2007 11:23
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

Verfasst: 3. Mai 2007 11:24
von Christian81
Qt gibt Fehlermeldungen in der Konsole aus.
im pro-File
CONFIG += conole

eingeben.
Dann siehst Du was falsch läuft.

Verfasst: 3. Mai 2007 11:38
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

Verfasst: 3. Mai 2007 11:42
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.

Verfasst: 3. Mai 2007 11:55
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':

Verfasst: 3. Mai 2007 11:58
von Christian81
nach dem Eintrag von Q_OBJECT qmake aufrufen !!!

Verfasst: 3. Mai 2007 12:12
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.

Verfasst: 3. Mai 2007 12:15
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

Verfasst: 3. Mai 2007 13:29
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