qt problem z obsługą zdarzeń

0

Witam, qt dopiero się uczę. Analizowałem sobie takie dwa kody, które teoretycznie powinny robić to samo:

#include <QtGui>

class MyWindow: public QWidget
{
public:
    MyWindow ();
    ~MyWindow () {};
protected:
    bool event (QEvent * event); 
private:
    QLabel *label1,*label2;
};

// konstruktor

MyWindow::MyWindow (): QWidget ()
{
    setGeometry (300,300,300,200);
    setWindowTitle ("Obsługa zdarzeń - wersja 1");
    label1 = new QLabel (this);
    label2 = new QLabel (this);
    label1 -> setGeometry (75,80,175,20);
    label2 -> setGeometry (75,110,175,20);
}

// obsługa zdarzeń

bool MyWindow::event (QEvent * event)
{
    // domyślnie akceptujemy zdarzenie
    event -> accept ();
    
    // przyciśnięcie przycisku klawiatury
    if (event -> type () == QEvent::KeyPress)
    {
        label1 -> setText ("QEvent::KeyPress");
        label2 -> setText (static_cast <QKeyEvent*>(event) -> text ()); 
        return true;
    }
    
    // zwolnienie przycisku klawiatury
    if (event -> type () == QEvent::KeyRelease)
    {
        label1 -> setText ("QEvent::KeyRelease"); 
        label2 -> setText (""); 
        return true;
    }

    // podwójne kliknięcie myszką
    if (event -> type () == QEvent::MouseButtonDblClick)
    {
        label1 -> setText ("QEvent::MouseButtonDblClick");
        QString x,y;
        x.setNum (static_cast <QMouseEvent*>(event) -> x ());
        y.setNum (static_cast <QMouseEvent*>(event) -> y ());
        label2 -> setText ("X = " + x + " Y = " + y); 
        return true;
    }
    
    // przyciśnięcie przycisku myszki
    if (event -> type () == QEvent::MouseButtonPress)
    {
        label1 -> setText ("QEvent::MouseButtonPress"); 
        QString x,y;
        x.setNum (static_cast <QMouseEvent*>(event) -> x ());
        y.setNum (static_cast <QMouseEvent*>(event) -> y ());
        label2 -> setText ("X = " + x + " Y = " + y); 
        return true;
    }

    // zwolnienie przycisku myszki
    if (event -> type () == QEvent::MouseButtonRelease)
    {
        label1 -> setText ("QEvent::MouseButtonRelease"); 
        label2 -> setText (""); 
        return true;
    }

    // przesunięcie kursora myszki
    if (event -> type () == QEvent::MouseMove)
    {
        label1 -> setText ("QEvent::MouseMove"); 
        QString x,y;
        x.setNum (static_cast <QMouseEvent*>(event) -> x ());
        y.setNum (static_cast <QMouseEvent*>(event) -> y ());
        label2 -> setText ("X = " + x + " Y = " + y); 
        return true;
    }

    // kursor myszki wkracza na obszar okna
    if (event -> type () == QEvent::Enter)
    {
        label1 -> setText ("QEvent::Enter"); 
        label2 -> setText (""); 
        return true;
    }

    // kursor myszki opuszcza obszar okna
    if (event -> type () == QEvent::Leave)
    {
        label1 -> setText ("QEvent::Leave"); 
        label2 -> setText (""); 
        return true;
    }
    
    // domyślnie obsługa zdarzenia przekazywana jest dalej
    return false;
}

int main(int argc, char *argv[])
{
    QApplication app (argc, argv);
    QTextCodec::setCodecForCStrings (QTextCodec::codecForName ("Windows-1250"));
    MyWindow window;
    window.show ();
    return app.exec();
}

i drugi:

#include <QtGui>

class MyWindow: public QWidget
{
public:
    MyWindow ();
    ~MyWindow () {};
protected:
    void keyPressEvent (QKeyEvent * event);
    void keyReleaseEvent (QKeyEvent * event);
    void mouseDoubleClickEvent (QMouseEvent * event);
    void mouseMoveEvent (QMouseEvent * event);
    void mousePressEvent (QMouseEvent * event); 
    void mouseReleaseEvent (QMouseEvent * event); 
    void enterEvent (QEvent * event);
    void leaveEvent (QEvent * event);
private:
    QLabel *label1,*label2;
};

// konstruktor

MyWindow::MyWindow (): QWidget ()
{
    setGeometry (300,300,300,200);
    setWindowTitle ("Obsługa zdarzeń - wersja 2");
    label1 = new QLabel (this);
    label2 = new QLabel (this);
    label1 -> setGeometry (75,80,175,20);
    label2 -> setGeometry (75,110,175,20);
}

// przyciśnięcie przycisku klawiatury

void MyWindow::keyPressEvent (QKeyEvent * event)
{
    label1 -> setText ("QEvent::KeyPress");
    label2 -> setText (event -> text ()); 
}

// zwolnienie przycisku klawiatury

void MyWindow::keyReleaseEvent (QKeyEvent * event)
{
    label1 -> setText ("QEvent::KeyRelease"); 
    label2 -> setText (""); 
}

// podwójne kliknięcie myszką

void MyWindow::mouseDoubleClickEvent (QMouseEvent * event)
{
    label1 -> setText ("QEvent::MouseButtonDblClick"); 
    QString x,y;
    x.setNum (event -> x ());
    y.setNum (event -> y ());
    label2 -> setText ("X = " + x + " Y = " + y); 
}

// przesunięcie kursora myszki

void MyWindow::mouseMoveEvent (QMouseEvent * event)
{
    label1 -> setText ("QEvent::MouseMove"); 
    QString x,y;
    x.setNum (event -> x ());
    y.setNum (event -> y ());
    label2 -> setText ("X = " + x + " Y = " + y); 
}

// przyciśnięcie przycisku myszki

void MyWindow::mousePressEvent (QMouseEvent * event)
{
    label1 -> setText ("QEvent::MouseButtonPress"); 
    QString x,y;
    x.setNum (event -> x ());
    y.setNum (event -> y ());
    label2 -> setText ("X = " + x + " Y = " + y); 
}

// zwolnienie przycisku myszki

void MyWindow::mouseReleaseEvent (QMouseEvent * event)
{
    label1 -> setText ("QEvent::MouseButtonRelease"); 
    label2 -> setText (""); 
}

// kursor myszki wkracza na obszar okna

void MyWindow::enterEvent (QEvent * event)
{
    label1 -> setText ("QEvent::Enter"); 
    label2 -> setText (""); 
}

// kursor myszki opuszcza obszar okna

void MyWindow::leaveEvent (QEvent * event)
{    
    label1 -> setText ("QEvent::Leave"); 
    label2 -> setText (""); 
}

int main(int argc, char *argv[])
{
    QApplication app (argc, argv);
    QTextCodec::setCodecForCStrings (QTextCodec::codecForName ("Windows-1250"));
    MyWindow window;
    window.show ();
    return app.exec();
}

Jednak po kompilacji, pierwszy program nie działa tak jak należy, w ogóle nie wyświetlają się etykiety. Czy ktoś wie co jest nie tak?

0

Źle obsługujesz zdarzenia!
Wzorzec jest taki:

bool MyWindow::event (QEvent * event)
{
     if (event -> type () == QEvent::KeyRelease) {
           ....
           return true;
     }
     ....

     return QWidget::event(event); // wywolanie tej metody dla kasy bazowej!
}

W ten sposób wszystkie nieobsłużone event'y zostaną właściwie przetworzone przez klasę bazową.
Zresztą w wielu wypadkach rekomendowane jest jedynie nasłuchiwanie zdarzenia i przekazywanie go klasie bazowej, np:

bool MyWindow::event (QEvent * event)
{
     if (event -> type () == QEvent::Resize) {
           ....
           return return QWidget::event(event);
     }
     ....
     return QWidget::event(event); // wywolanie tej metody dla kasy bazowej!
}

Nawet te dedykowane zdarzenia czasami powinny być też tak potraktowane, dokumentacja zwykle mówi jak należy obsługiwać dane zdarzenia i czy klasa bazowa powinna mieć zawsze możliwość ich obsłużenia.

0

Ok, dzięki wszystko teraz działa jak należy ;)

1 użytkowników online, w tym zalogowanych: 0, gości: 1