Einbinden von Timer über Auto-Connect



  • Hallo erstmal,
    Ich lerne (immer noch) C++ und habe im Mainwindow ein Label eingebunden, über das ich Zeichenaktionen ausgeben kann.
    Dieses Label möchte ich über einen Timer ansteuern, um Bewegungen darzustellen, aber ich kann den Timer nicht einbinden.
    Mal die Kurzform vom Code ohne alle Includes:

    MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent),
    ui(new Ui::MAinWindow)
    {
           ui->setupUi(this);
    
          zeichenLabel = new QLabel
    
          myTimer = new QTimer;
          myTimer->start(1000);
          QObject::connect(myTimer, SIGNAL(timeout()), zeichenLabel, SLOT(zeichne()));
    }
    
    MainWindow::~MainWindow()
    {
          delete ui;
    }
    
    void MainWindow::zeichne()
    {
          if (myTimer->isActive())
                zeichenLAbel_>setText("Hallo");
    

    Ich wollte erst den Timer den implemetieren, und dann im Slot vom Timer das Zeichnen bewegen. (falls das klappt). Das Zeichnen vorher hat immer schon geklappt, aber der Timer war immer das Problem.

    Hier bekomme ich immer die Meldung:
    QObject::connect: Cannot connect QTimer::timeout() to(NULL): zeichne()

    Was mache ich falsch? Oder wie kann ich den Timer richtig einbinden?

    Schon im Voraus Danke

    Steevie

    [edit: koahnig, code formatting tics set]


  • Moderators

    @steevie

    Schaue dir einmal im zweiten Beispiel die Deklaration an. Dort wird unter "public slots:" eine slot-Routine deklariert. Du verwendest wahrscheinlich nur eine normale Routine.



  • Danke für die Antwort,
    ich habe es schon unter "public slots" gesetzt, aber ich habe keine eigene Klasse für den Timer erstellt.
    Mir ist gesagt worden, dass das nicht nötig wäre, und ich einfach von QTimer ein Objekt über einen Pointer erzeugen soll.
    Das ist in meinem Fall "myTimer".
    Den Slot erstelle ich in der Klasse "MainWindow"
    Aber dann klappt das mit dem Slot nicht (jedenfalls bei mir nicht).
    Oder ist es doch einfacher, eine eigene Klasse für den Timer zu erstellen, um mit dem Slot weniger Probleme zu haben?

    Danke schon im Voraus

    Stephan


  • Moderators

    @steevie

    Ändere

          QObject::connect(myTimer, SIGNAL(timeout()), zeichenLabel, SLOT(zeichne()));
    

    nach

          connect(myTimer, SIGNAL(timeout()), this, SLOT(zeichne()));
    

    Ich habe nicht genau gelesen. "zeichenLabel" ist ja wohl nur ein QLabel und "zeichne()" ist ein Member von MainWindow.
    Eventuell ist die Functor-basierende Schreibweise besser hier.

          connect(myTimer, &QTimer::timeout, this, &MainWindow::zeichne );
    

    Damit hättest du schon einen Fehler beim Kompilieren erzeugt.



  • Danke,
    das mit "this" hatte ich schon probiert, jetzt noch mal, aber das Programm stürzt ab.

    bei der zweiten Version habe ich sofort einen fatalen Fehler (mit dem roten Kreuz) und das Programm schmiert ab.
    Die Syntax wird vom Programm akzeptiert, aber im Speicherbereich haue ich wahrscheinlich alles kaputt.
    Ich versuchs weiter.

    Steevie


  • Moderators

    @steevie

    Du kannst dies mit dem Debugger prüfen wann das Ganze abstürzt. Dies ist meist die beste Lösung.
    Ich gehe davon aus, dass du die Pointer für myTimer und zeichenLabel in der deklaration vereinbart hast.
    Desweiteren hast du noch ein paar Gross-/Kleinschreibungsfehler in er letzten Zeile:

    void MainWindow::zeichne()
    {
          if (myTimer->isActive())
                zeichenLAbel_>setText("Hallo");
    

    Allerdings sollte dies beim Kompilieren schon auffallen.



  • Da ich alles nur getippt habe, kann die Groß/Kleinschreibung schon mal daneben sein, aber da meckert Qr ja gleich :-)
    Hier masl der Code aus der Header-Datei:

    #ifndef MAINWINDOW_H
    #define MAINWINDOW_H
    
    #include <QMainWindow>
    #include <QLabel>
    #include <QTimer>
    #include <QPainter>
    
    namespace Ui {
    class MainWindow;
    }
    
    class MainWindow : public QMainWindow
    {
        Q_OBJECT
        
    public:
        explicit MainWindow(QWidget *parent = 0);
        ~MainWindow();
    
    QLabel *zeichenLabel;
    QTimer *myTimer;
    QPainter *myPainter;
    QPixmap *myPixmap;
    
    
    public slots:
    void zeichne();
    
        
    private:
        Ui::MainWindow *ui;
    };
    
    #endif // MAINWINDOW_H
    
    
    und dann gleich noch die Main:
    
    #include "mainwindow.h"
    #include <QApplication>
    
    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
        MainWindow w;
        w.show();
        
        return a.exec();
    }
    

    Ich hatte es vorher noch komplexer und habe noch einen "QPaintEvent" mit eingebunden (und das Zeichnen hat ja auch geklappt), nur mit dem Timer nicht. Und dann habe ich alles rausgeschmissen, was nicht zum Timer gehört, um erst einmal das Problem zu lösen, um dann einen funktioniereden Slot vom Timer zu erzeugen, in dem ich dann das Zeichnen übernehmen kann.

    Der Absturz kommt gleich in der connect-Anweisung.

    Danke für die Hilfe bisher.
    Ich versuchs weiter.

    Steevie


  • Moderators

    @steevie

    Starte vielleicht erst den Timer nach dem connect. Kann mir aber nicht direkt vorstellen, warum das ein Problem sein sollte.
    Im Debugger könnte vielleicht das connect mit dem Auslösen des Timer kollidieren.

    Ansonsten noch einmal "run qmake" und rebuild.



  • @koahnig

    Also Qmake und rebuild habe ich ein paar mal gemacht
    Jetzt habe ich eine neue Klasse für den Timer gebildet, und der Timer funktioniert jetzt. Ich kann ihn starten, aber jetzt geht das Einbinden der Zeichenfunktion nicht.
    Den QPaintEvent kann ich als Funktion ja nicht in einen Slot integrieren, ob ohne den Pain Event kann ich den Painter nicht starten.
    Irgendwelche Tipps?

    Hier die Header-Datei:

    #ifndef MEINTIMER_H
    #define MEINTIMER_H
    
    #include <QtCore>
    #include <QWidget>
    #include <QtGui>
    #include <QApplication>
    
    class MeinTimer : public QWidget
    {
        Q_OBJECT
    
    public:
    
        QPainter *myPainter;
        int zeitDauer;
        int bleibendeZeit;
        int anzahl;
        int x ;
        int y;
        int hoehe;
        int breite;
    
        MeinTimer();
        QTimer *kreisTimer;
    
        //die Funktionen
        void kreisTimerAktiv();
        void kreisTimerStart();
        void kreisTimerStop();
    
    public slots:
        void kreisTimerSlot();
    
    protected:
        void paintEvent(QPaintEvent *);
    };
    #endif // MEINTIMER_H
    

    und die cpp:

    #include "meintimer.h"
    #include <QtCore>
    #include <QDebug>
    #include <QPainter>
    #include <QApplication>
    #include <QtWidgets>
    
    MeinTimer::MeinTimer()
    {
        resize(750, 750);
        setWindowTitle("Kreisbewegung");
    
        myPainter = new QPainter(this);
        x = 10;
        y = 10;
        hoehe = 100;
        breite = 100;
    
        zeitDauer = 2000;
        anzahl = 0;
        kreisTimer = new QTimer(this);
    
        connect(kreisTimer, SIGNAL(timeout()), this, SLOT(kreisTimerSlot()));
        kreisTimer->setInterval(zeitDauer);
        kreisTimer->start();
    
        bleibendeZeit = kreisTimer->remainingTime();
        qDebug() << "bleibende Zeit: " << bleibendeZeit ;
    }
    
    void MeinTimer::kreisTimerAktiv()
    {
        if(kreisTimer->isActive())
        {
            anzahl = anzahl + 1;
            x = x + 5;
            y = y + 5;
    
            qDebug() << "Timer arbeitet" << anzahl;
        }
    }
    
    void MeinTimer::paintEvent(QPaintEvent *)
    {
       myPainter->begin(this);
    
       myPainter->drawRect(x, y, hoehe, breite);
    }
    
    void MeinTimer::kreisTimerSlot()
    {
        qDebug() << "Timer ausgeführt";
    
        kreisTimerAktiv();
    }
    
    void MeinTimer::kreisTimerStart()
    {
        kreisTimer->start();
    }
    
    void MeinTimer::kreisTimerStop()
    {
        kreisTimer->stop();
    }
    

    und noch die Main:

    #include <QApplication>
    #include "meintimer.h"
    
    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
        MeinTimer w;
        MeinTimer mTimer;
    
        w.show();
        
        return a.exec();
    }
    

    Wenn ich in der Funktion PaintEvent zeichen, geht das, aber dann kann ich die Koordinaten nicht verändern, die ich mit dem Timer verändern will.
    Wenn ich im TimerSlot zeichznen möchte, dann startet der Painter nicht.
    Jetzt gehe ich schlafen und schau mir das morgen noch mal an.

    Übrigens: Allen ein gutes Neues JAhr 2017

    Steevie

    [edit: koahnig codetags added]


  • Moderators

    @steevie

    Versuche es einmal mit einem repaint oder update in der Timer-Slot-Routine



  • Danke,

    der Tip war Gold wert.!!
    Jetzt bewegt sich was!
    Von hier aus kann ich weitermachen.
    Wenn alles funktioniert gebe ich Bescheid!

    Steevie



  • @steevie said in Einbinden von Timer über Auto-Connect:

    Danke,

    der Tip war Gold wert.!!
    Jetzt bewegt sich was!
    Von hier aus kann ich weitermachen.
    Wenn alles funktioniert gebe ich Bescheid!

    Steevie

    Also es funktioniert, und ich möchte mich herzlich bedanken

    Steevie


  • Moderators

    @steevie

    Gern geschehen. Schön zu wissen, dass es geholfen hat.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.