Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

[QT] (Windows) Problem z prostą obsługą zdarzeń

Ostatnio zmodyfikowano 2011-01-09 12:17
Autor Wiadomość
cyklopek11
Temat założony przez niniejszego użytkownika
[QT] (Windows) Problem z prostą obsługą zdarzeń
» 2011-01-08 23:35:34
Siedzę już dwie godziny nad przykładem 14.2 Obsługa zdarzeń - wersja 1. z książki: "Wykorzystaj potęgę aplikacji graficznych" J. Ganczarskiego" i mam problem z prawidłowym działaniem prostego kodu obsługującego zdarzenie. Kod jest następujący :

C/C++
#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();
}
Jest to proste okno klasy bazowej QWidget "na którym" mniej więcej po środku są dwa widgety typu QLabel. Pierwszy label ma wyświetlać rodzaj zdarzenia (a więc naciśnięcie klawisza klawiatury, zwolnienie klawisza itd w formie typu wyliczeniowego ale to nieważne a drugi dodatkowe informacje ale to też nieistotne). Po skompilowaniu i uruchomieniu pokazuje się puste okno. Dopóki okno jest aktywne labele nie wyświetlają żadnych informacji. Jeśli zminimalizuje to okno lub aktywuję inne okno w moim komputerze i powrócę to tego okna to czasem załapie jakieś zdarzenie, label je wyświetli i tak już wyświetla cały czas dopóki to okno jest aktywne. I tak w kółko. Kod jest niby teoretycznie ok, dodatkowo w przeładowywanej metodzie event dla kontroli dodałem linijkę aby wyświetlać w konsoli (std::cout) czy ta metoda działa wogóle i wszystko jest ok. Moim zdaniem jest tu jakiś wewnętrzny problem ze zdarzeniami między klasą QWidget a moją klasą pochodną. Może jakiś specjalista od Qt rzuci na ten kod ( i jego wynik) okiem...

P-26366
malan
» 2011-01-09 01:32:31
Specjalistą od QT nie jestem, ale obstawiam, że masz źle zaimplementowaną metodę event. Podaruj sobie własną implementację i zrób to za pomocą connect...
P-26374
cyklopek11
Temat założony przez niniejszego użytkownika
» 2011-01-09 11:27:16
Implementacja jak napisałem wygląda teoretycznie dobrze aczkolwiek być może coś jest nie tak. Obsługę connect mam opanowaną natomiast mnie interesuje teraz niskopoziomowa obsługa zdarzeń właśnie przy pomocy event i nie odpuszczę tego!
P-26376
malan
» 2011-01-09 11:51:28
Znalazłem przykład:
Events and Event Filters (Event Handlers)
C/C++
bool MyWidget::event( QEvent * event )
{
    if( event->type() == QEvent::KeyPress ) {
        QKeyEvent * ke = static_cast < QKeyEvent *>( event );
        if( ke->key() == Qt::Key_Tab ) {
            // special tab handling here
            return true;
        }
    } else if( event->type() == MyCustomEventType ) {
        MyCustomEvent * myEvent = static_cast < MyCustomEvent *>( event );
        // custom event handling here
        return true;
    }
   
    return QWidget::event( event );
}
Nie zwracają tutaj
false
 tak jak Ty, tylko
QWidget::event( event );
. Może to jest przyczyna Twoich błędów? ;>
P-26377
cyklopek11
Temat założony przez niniejszego użytkownika
» 2011-01-09 12:17:40
Wielkie dzięki działa! Tak w sumie kręciłem się koło tego ostatniego returna, nakombinowałem się pod górkę ale nic z tego nie wyszło. Poprawiam w takim razie błąd w książce.
P-26378
« 1 »
  Strona 1 z 1