QT Slots (connect) Anfängerproblem (Signal kommt nicht an)
-
Hallo zusammen.
Ich versuche mich in QT, habe mir die Source geholt und kompiliert und einige Beispiele ausprobiert. Alles funktioniert.
Für VS2008pro habe ich das VSaddin installiert und ein neues QT Projekt erstellt. Dann habe ich im Designer eine simple GUI gebaut, ein Signal dort schon verbunden und kompiliert. Alles funktioniert.
Nun habe ich einen eigenen Slot definiert und mit connect die Action verbunden. Aber das funktioniert nicht.
Ich finde keinen Fehler, es sieht alles aus, wie in den Beispielen. Hier im Forum ist auch ein Posting, das ein ähnliches Problem behandelt. Nur leider hilft das bei mir nicht.
Hier die relevanten Dateien:
main.cpp
#include "stdafx.h" #include "test.h" #include <QtGui/QApplication> int main(int argc, char *argv[]) { QApplication App(argc, argv); Test MainWin; MainWin.show(); return App.exec(); }
test.h
#ifndef TEST_H #define TEST_H #include <QtGui/QMainWindow> #include "ui_test.h" class Test : public QMainWindow { Q_OBJECT public: Test(QWidget *parent = 0, Qt::WFlags flags = 0); ~Test(); private: Ui::TestClass ui; protected slots: void OpenFile(); }; #endif // TEST_H
test.cpp
#include "stdafx.h" #include "test.h" Test::Test(QWidget *parent, Qt::WFlags flags) : QMainWindow(parent, flags) { ui.setupUi(this); connect(ui.actionOpen, SIGNAL(triggered()), qApp, SLOT(Test::OpenFile())); } Test::~Test() { } void Test::OpenFile() { QFileDialog::getOpenFileName(this); QMessageBox::information(this, tr("MainWindowMessage"), tr("Open File")); }
ui_test.h
/******************************************************************************** ** Form generated from reading ui file 'test.ui' ** ** Created: Sat 18. Jul 20:21:13 2009 ** by: Qt User Interface Compiler version 4.5.2 ** ** WARNING! All changes made in this file will be lost when recompiling ui file! ********************************************************************************/ #ifndef UI_TEST_H #define UI_TEST_H #include <QtCore/QVariant> #include <QtGui/QAction> #include <QtGui/QApplication> #include <QtGui/QButtonGroup> #include <QtGui/QHeaderView> #include <QtGui/QMainWindow> #include <QtGui/QMenu> #include <QtGui/QMenuBar> #include <QtGui/QStatusBar> #include <QtGui/QToolBar> #include <QtGui/QWidget> QT_BEGIN_NAMESPACE class Ui_TestClass { public: QAction *actionOpen; QAction *actionSave; QAction *actionQuit; QWidget *centralWidget; QMenuBar *menuBar; QMenu *menuDatei; QMenu *menuOptionen; QToolBar *mainToolBar; QStatusBar *statusBar; void setupUi(QMainWindow *TestClass) { if (TestClass->objectName().isEmpty()) TestClass->setObjectName(QString::fromUtf8("TestClass")); TestClass->resize(600, 400); actionOpen = new QAction(TestClass); actionOpen->setObjectName(QString::fromUtf8("actionOpen")); actionSave = new QAction(TestClass); actionSave->setObjectName(QString::fromUtf8("actionSave")); actionQuit = new QAction(TestClass); actionQuit->setObjectName(QString::fromUtf8("actionQuit")); centralWidget = new QWidget(TestClass); centralWidget->setObjectName(QString::fromUtf8("centralWidget")); TestClass->setCentralWidget(centralWidget); menuBar = new QMenuBar(TestClass); menuBar->setObjectName(QString::fromUtf8("menuBar")); menuBar->setGeometry(QRect(0, 0, 600, 21)); menuDatei = new QMenu(menuBar); menuDatei->setObjectName(QString::fromUtf8("menuDatei")); menuOptionen = new QMenu(menuBar); menuOptionen->setObjectName(QString::fromUtf8("menuOptionen")); menuOptionen->setContextMenuPolicy(Qt::DefaultContextMenu); TestClass->setMenuBar(menuBar); mainToolBar = new QToolBar(TestClass); mainToolBar->setObjectName(QString::fromUtf8("mainToolBar")); TestClass->addToolBar(Qt::TopToolBarArea, mainToolBar); statusBar = new QStatusBar(TestClass); statusBar->setObjectName(QString::fromUtf8("statusBar")); TestClass->setStatusBar(statusBar); menuBar->addAction(menuDatei->menuAction()); menuBar->addAction(menuOptionen->menuAction()); menuDatei->addAction(actionOpen); menuDatei->addAction(actionSave); menuDatei->addAction(actionQuit); retranslateUi(TestClass); QObject::connect(actionQuit, SIGNAL(triggered()), TestClass, SLOT(close())); QMetaObject::connectSlotsByName(TestClass); } // setupUi void retranslateUi(QMainWindow *TestClass) { TestClass->setWindowTitle(QApplication::translate("TestClass", "Test", 0, QApplication::UnicodeUTF8)); actionOpen->setText(QApplication::translate("TestClass", "Open", 0, QApplication::UnicodeUTF8)); actionSave->setText(QApplication::translate("TestClass", "Save", 0, QApplication::UnicodeUTF8)); actionQuit->setText(QApplication::translate("TestClass", "Quit", 0, QApplication::UnicodeUTF8)); menuDatei->setTitle(QApplication::translate("TestClass", "File", 0, QApplication::UnicodeUTF8)); menuOptionen->setTitle(QApplication::translate("TestClass", "Options", 0, QApplication::UnicodeUTF8)); } // retranslateUi }; namespace Ui { class TestClass: public Ui_TestClass {}; } // namespace Ui QT_END_NAMESPACE #endif // UI_TEST_H
Ich hoffe, jemand kann mir helfen, da ich wirklich nicht weiß, was hier falsch ist. Es kompiliert ohne Fehler.
-
Du hast Qt Signal/Slot nicht verstanden. Lies dir die Beispiele GENAU durch!
Es gibt ganz viele im qt-sourcetree unter examples und demos.Aber dass du auf die Schnelle weiter kommst hier die Lösung:
Nichtconnect(ui.actionOpen, SIGNAL(triggered()), qApp, SLOT(Test::OpenFile()));
sondern
connect(ui.actionOpen, SIGNAL(triggered()), this, SLOT(OpenFile()));
Warum das so ist? Das Zielobjekt (3. Parameter) muss den Slot (4.Parameter) selber haben (QApplication hat kein "Test::OpenFile()"), und das was in SLOT steht ist NUR der Methodenname, ohne Klasse!
Aber wie gesagt, DOKU, wie sie zu connect steht:
http://doc.qtsoftware.com/4.5/qobject.html#connect
Genau dein Ding, BabyUnd zu guter letzt: Fehler bei connect werden in der Console (Windows prompt) angegeben, da wärst du dann sofort drauf gekommen...
-
Ups. qApp hatte ich nur versucht, eben weil this nicht funktioniert hatte.
Das Problem war
SLOT(OpenFile())
anstelle von
SLOT(Test::OpenFile())
Ich dachte mir, das ist einfach ein Namespace und daher habe ich das auch qualifiziert geschrieben.
Warum das so ist, muss ich wohl noch verstehen.
Vielen Dank erstmal
Ansonsten hätte ich noch eine kleine Frage:
Kann ich die selbst erstellten Slots auch im QT-Designer anzeigen lassen bzw. verwenden?
Mir ist schon klar, dass es hier um eine Trennung zwischen GUI und App geht, aber entweder alles im Sourcecode oder eben im Designer. Gibt es da eine Möglichkeit?Danke auf jeden Fall
-
Ach und mit der Konsole hatte ich das auch schon versucht. Also Test.exe in der Konsole starten. Kamen keine Fehler (eben mit this, aber auch mit Test::OpenFile())
Und eine .pro Datei habe ich nicht.
-
QTAnfänger schrieb:
Ansonsten hätte ich noch eine kleine Frage:
Kann ich die selbst erstellten Slots auch im QT-Designer anzeigen lassen bzw. verwenden?Du kannst für den Designer eigene Plugins schreiben. Darin kannst du deine Signals/Slots direkt verwenden.
Was ich noch nicht ausprobiert hab:
Rechtsclick im Designer auf ein beliebiges Widget -> Change Signals/Slots, und hier einen beliebigen Slot einfügen. Den kannst du dann (mit korrektem Reciever) auch als SLOT auswählen.
Sollte aber genau das machen, wonach es sich anhört...Und um unter Windows Ausgaben auf der Console zu bekommen, gehört "CONFIG += console" in das .pro. Und wenn du dich weigerst, diese .pro zu nutzen, musst du dich eben umschaun, wie du VisualDingsBums konfigurierst, dass Output auf der Console landet
-
Ja, VisualDingsBums ist eigentlich auch nicht so meins. Aber makefiles auch nicht.
In der Debugausgabe kam auf jeden Fall kein Fehler, als ich Test::OpenFile() verwendet hatte. Hab's mal versucht und einen Fehler provoziert, der wurde dann auch angezeigt (also Signalfehler). Also hätte ich hier auch mit .pro wohl keine Meldung bekommen.Aber dennoch werde ich mir die .pro Datei mal genauer ansehen.
Und das mit den Plugins wohl auch, denn dieses Slot-Menü listet auch nur auf, was von QT da ist.Also nochmal - vielen Dank
Ich hätte den Fehler nie gefunden, denn das mit Empfänger ist mir schon klar. Nur ist es ungewohnt für mich, dass ich den Namespace weglassen muss.
-
QTAnfänger schrieb:
denn dieses Slot-Menü listet auch nur auf, was von QT da ist.
Unter der Liste ist doch ein "+"? Drauf klciken gibt nen neuen SLOT den du nach deinem Gusto benennen kannst. Werd mir das doch mal schnell anschaun.
-
Jay doch. Warst schneller. Ich wollte gerade schreiben, dass es doch geht. Hatte es gerade versucht.
-
Ja das funktioniert perfekt
Ich muss mich wirklich noch etwas in die QT Sichtweise einarbeiten.Nanostar, mein Held