Signal & Slots ist eine Qt spezifische C++ Erweiterung.
// Beispiel zum SIGNAL-SLOT-Mechanismus // #include<QObject> #include<iostream> using namespace std; // Eine Klasse, die Signals und Slots besitzt. class Foo : public QObject { Q_OBJECT; public: Foo(); // Konstruktor int value() const { return val; } public slots: // Der Wert von "val" wird geändert. void setValue( int ); signals: // Das Signal soll ausgesandt werden, wenn "val" geändert wird. void valueChanged( int ); private: int val; }; Foo::Foo() { val = 1; } void Foo::setValue( int v ) { // val wird nur neu gesetzt, wenn tatsächlich ein anderer Wert übergeben wird. if ( v != val ) { val = v; emit valueChanged(v); } } #include"sigslot.moc" int main() { // Zwei Foo-Objekte Foo *a = new Foo(); Foo *b = new Foo(); // Das Signal des einen wird mit dem Slot des anderen Objekts verbunden. QObject::connect(a, SIGNAL(valueChanged(int)), b, SLOT(setValue(int))); b->setValue( 11 ); // b.val hat den Wert 11 cout << "\nb:" << b->value() << "\n" ; a->setValue( 79 ); // a.val hat den Wert 79 und durch die obige Verknüpfung // hat auch b.val den Wert 79 cout << "\na:" << a->value() << "\n" ; cout << "b:" << b->value() << "\n\n" ; return 0; }
connect(Sender-obj, SIGNAL(signal-name(type)), receiv-obj, SLOT(member-func(type)));
// Knopf mit Funktion: wenn man draufdrueckt beendet sich das Programm. // Signal und Slot beide vor-definiert #include <QApplication> #include <QPushButton> #include <QWidget> class MyWidget : public QWidget { public: MyWidget(void); private: QPushButton *ende; }; MyWidget::MyWidget(void) { ende = new QPushButton("Raus hier!",this); ende->setGeometry(10,10,100,30); // qApp ist ein globaler Zeiger auf QApplication QObject::connect(ende,SIGNAL(clicked()),qApp,SLOT(quit())); } int main(int argc,char** argv) { QApplication app(argc,argv); QWidget* mywidget = new MyWidget(); mywidget->resize(120,50); mywidget->show(); return app.exec(); }
Beispiel mit Knopf und eigenem Slot
// Knopf mit Funktion: jetzt selbst-definierte Aktion. // // erst mit moc drueber: $QTDIR/bin/moc -o drueckmich.moc drueckmich.C #include <QApplication> #include <QPushButton> #include <QObject> class MyWidget : public QWidget { Q_OBJECT; public: MyWidget(void); public slots: void autsch(void); private: QPushButton *ende; }; MyWidget::MyWidget(void) { ende = new QPushButton("Drueck mich!",this); ende->setGeometry(10,10,200,40); // qApp ist ein globaler Zeiger auf QApplication QObject::connect(ende,SIGNAL(clicked()),this,SLOT(autsch())); } void MyWidget::autsch() { ende->setText("Aua, nicht so grob !"); } #include "drueckmich.moc" int main(int argc,char** argv) { QApplication app(argc,argv); QWidget* mywidget = new MyWidget(); mywidget->resize(120,50); // app.setMainWidget(mywidget); mywidget->show(); return app.exec(); }
// addInt.C #include <QApplication> #include <QLineEdit> #include <QLabel> #include <QPushButton> #include <QLayout> #include <QString> class MyWidget : public QWidget { Q_OBJECT; public: MyWidget(void); public slots: void addint(void); private: QPushButton *add; QLineEdit* num1 ; QLineEdit* num2 ; QLineEdit* num3 ; }; MyWidget::MyWidget(void) { num1 = new QLineEdit(this); // Text-Feld num1->setText( "0" ); num2 = new QLineEdit(this); // Text-Feld num2->setText( "0" ); num3 = new QLineEdit(this); // Text-Feld num3->setText( "0" ); QPushButton *qpb = new QPushButton("Add",this); // Knopf QLabel *qlab = new QLabel("Result",this); // label QVBoxLayout* layout = new QVBoxLayout(this); layout->addWidget(num1); layout->addWidget(qpb); layout->addWidget(num2); layout->addWidget(qlab); layout->addWidget(num3); // QObject::connect(qpb,SIGNAL(clicked()),this,SLOT(addint())); // button => addint QObject::connect(num1,SIGNAL(returnPressed()),this,SLOT(addint())); // textfield => addint QObject::connect(num2,SIGNAL(returnPressed()),this,SLOT(addint())); } void MyWidget::addint() { // add 2 integers int v1 = (num1->text()).toInt(); // QString ==> int int v2 = (num2->text()).toInt(); int v3 = v1 + v2; QString qs; qs.setNum(v3); // int ==> QString num3->setText(qs); } #include "addInt.moc" int main(int argc,char** argv) { QApplication app(argc,argv); QWidget* mywidget = new MyWidget(); mywidget->resize(120,130); mywidget->show(); return app.exec(); }
// moveCircle3.C // #include <QApplication> #include <QMenuBar> #include <QMessageBox> #include <QPainter> #include <QPixmap> #include <QWidget> #include <QResizeEvent> #include <QMouseEvent> #include <QPaintEvent> #include <QScrollArea> #include <QColorDialog> #include <iostream> #include <cmath> class myDraw : public QWidget // Zeichen--Widget { Q_OBJECT; public: myDraw(); public slots: void setColor( QColor ); QColor getColor() ; protected: virtual void paintEvent(QPaintEvent*); virtual void mousePressEvent( QMouseEvent* ); virtual void mouseMoveEvent( QMouseEvent* ); private: int xpos, ypos, radius; // circle parameters QColor mycol; }; /// Separate Klasse fuer Haupt-Widget class myWindow : public QWidget { Q_OBJECT public: myWindow(); private slots: void slotAbout(); void slotAboutQt(); void slotColorMenu( ); void slotColorRed( ); void slotColorYellow( ); void slotColorBlue( ); signals: void colorChanged( QColor ); protected: virtual void resizeEvent( QResizeEvent* ); private: QMenuBar *menubar; QMenu *filemenu; QMenu *colormenu; QMenu *helpmenu; QScrollArea *scrollarea; myDraw *mydr; }; #include "moveCircle3.moc" // Implementations myDraw::myDraw() { xpos = 50; ypos = 50; radius = 40; mycol = Qt::yellow; setBackgroundRole(QPalette::Base); setAutoFillBackground(true); } void myDraw::paintEvent(QPaintEvent* ) { QBrush b1( mycol ); QPainter *paint = new QPainter(); paint->begin( this); paint->setPen( Qt::red ); paint->setBrush( b1 ); paint->drawEllipse( xpos, ypos, radius, radius ); paint->end(); } // reagiert auf Maus-Klick void myDraw::mousePressEvent( QMouseEvent* event ) { xpos = (event->pos()).x(); ypos = (event->pos()).y(); update(); } // reagiert auf Mausbewegung, waehrend eine Taste gedrueckt ist. void myDraw::mouseMoveEvent( QMouseEvent* event ) { xpos = (event->pos()).x(); ypos = (event->pos()).y(); update(); } void myDraw::setColor( QColor new_color ) { mycol = new_color; update(); } QColor myDraw::getColor( ) { return( mycol ); } myWindow::myWindow() { // setup menues // first three popup-menues filemenu = new QMenu("File"); filemenu->addAction( "&Quit", qApp, SLOT( quit() ) ); colormenu = new QMenu("Color"); colormenu->addAction( "Red", this, SLOT( slotColorRed( ))); colormenu->addAction( "Yellow", this, SLOT( slotColorYellow( ))); colormenu->addAction( "Blue", this, SLOT( slotColorBlue( ))); colormenu->addAction( "Set color ...", this, SLOT( slotColorMenu( ))); helpmenu = new QMenu("Help"); helpmenu->addAction( "&About MoveCircle", this, SLOT( slotAbout() ) ); helpmenu->addAction( "About &Qt", this, SLOT( slotAboutQt() ) ); // create menubar in widget and add the 3 popup-menues menubar = new QMenuBar( this ); menubar->addMenu(filemenu ); menubar->addMenu( colormenu ); // menubar->insertSeparator(); menubar->addMenu(helpmenu ); // Hier wird ein ScollArea definiert scrollarea = new QScrollArea( this ); scrollarea->setGeometry( 0, menubar->height(), width(), height() - menubar->height() ); // Die Malflaeche wird in ausreichender Groesse erzeugt. mydr = new myDraw(); mydr->setGeometry( 0, 0, 1000, 1000 ); // und in die ScrollArea eingefügt. scrollarea->setWidget( mydr ); // Verknuepfung des Signals colorChanged() mit dem Slot setColor() // der Malfläche zum Setzen der Farbe QObject::connect( this, SIGNAL( colorChanged( QColor ) ), mydr, SLOT( setColor( QColor ) ) ); } // Bei einer Veränderung der Größe muss ScrollArea angepasst werden. void myWindow::resizeEvent( QResizeEvent* ) { scrollarea->setGeometry( 0, menubar->height(), width(), height() - menubar->height() ); } void myWindow::slotAbout() { QMessageBox::information( this, "About QtTriangle 2", "This is the MoveCircle application\n" "No Copyright by Nobody\n"); } void myWindow::slotAboutQt() { QMessageBox::aboutQt( this, "About Qt" ); } // dieser Slot setzt die Farbe nicht direkt, da die zugehörige // Datenstruktur nicht zur selben Klasse gehört. // Statt dessen wird ein Signal ausgesandt. void myWindow::slotColorMenu( ) { QColor col = QColorDialog::getColor(mydr->getColor(), this); if (!col.isValid()) return; colorChanged(col); } void myWindow::slotColorRed( ) { colorChanged(Qt::red); } void myWindow::slotColorYellow( ) { colorChanged(Qt::yellow); } void myWindow::slotColorBlue( ) { colorChanged(Qt::blue); } int main(int argc, char **argv) { QApplication app(argc,argv); myWindow *wid = new myWindow(); wid->resize(300,300); wid->show(); return app.exec(); }
1. Von QMenu colormenu Signal zu SLOT myWindow::slotColorMenu() Member-Funktion
2.
myWindow::slotColorMenu() schickt
colorChanged(color) Signal zu
SLOT
myDraw::setColor( QColor ) Member-Funktion
GDuckeck 2019-08-01