@Marius.Maximus już wiem czemu mi nie działała klawiatura tak, jak oczekiwałem. No cóż wkurzają mnie te lakoniczne opisy klas - jakby to był jakiś bełkot naukowy dla wtajemniczonych, jak jestem twórcą czegoś, to wiem jak to działa i jakie są zależności - mogliby chociaż tam jakoś to wszystko treściwie opisać, że np "nie da się zmapować od nowa wczytywania klawiatury bo to dzieje się na jakimś innym poziomie" np na poziomie jądra, a klasa tylko ma uchwyt do wywołania w jądrze i klasa QKeyEvent tylko i wyłącznie obiera zdarzenia z klawiatury i tą klasę można wykorzystać tylko i wyłącznie do wychwytywania wpisanych znaków i skrótów klawiaturowych z klawiatury - i kurde, życie było by od razu prostsze, a nie piszą jakieś ogólniki udające jakiegoś edukowanego ludka tudzież profesóra The QKeyEvent class describes a key event
- co według nich znaczy "opisuje" - dobra, nie chce mi się nad tym rozwodzić ale wkurzają mnie te zbyt ogólne opisy z których nic nie wynika i domyślaj się człowieku co autor miał na myśli... ale do rzeczy
dlaczego nie działała klawiatura tak jak opisałem to w poście? Dla przypomnienia, pisałem, że
- wciskam i trzymam klawisz shift to mam duże litery
- wciskam klawisz capsLock to mam duże litery
- ale jak nie zauważę, że mam włączony capsLock i wcisnę dodatkowo klawisz shift to mam małe litery, bo klawisz shift w tym momencie znosi działanie capsLocka - jak nie wierzysz, to przetestuj to u siebie w notatniku i zobacz
nie da się tego zrobić. Z prostego powodu - przyznam kolesiom, że mają finezję i piszą genialnie kod ale opisy wszystkiego w dokumentacji mają do D $ %
- szkoda, że nie ma większej czcionki takiej na 100 pt !!!
więc jest taka fajna funkcja o nazwie event
- za bardzo skupiłem swoją uwagę na tych dwóch funkcjach keyPressEvent
and keyReleaseEvent
. Więc kolega @Marius.Maximus miał rację żeby dać cały kod, a nie jakiś kawałek, bo wydaje nam się, że tam jest problem ale tak naprawdę nie musi... no ale w moim przypadku nie wiem czy by to coś dało, bo ja sam nie rozumiem jak wiele rzeczy działa i nie dam rady doprecyzować pytania w taki sposób aby dało się was nakierować na rozwiązanie - jedynie mogę powiedzieć robię taką czynność i oczekuję na wyjściu tego
- dobra więc o co chodzi z tymi trzema funkcjami i dlaczego to nie działało jak lamer myślał. Ano powód jest banalny - przynajmniej tak to rozumiem.
- Qt - biblioteka jako całość odbiera wywołania z jądra - nie obsługuje sprzętu na niskim poziomie - w tym przypadku mowa o klawiaturze i na tym się skupiam - bo chyba byłby to bezsens, skoro na dzień dobry klawiaturę obsługuje system operacyjny i z przerwań można odczytać co klepie ludek
- skoro system operacyjny załatwia warstwę abstrakcyjną sprzętu - to dlaczego nie napisać funkcji
event
i tam odbierać wywołania z jajka, a zadaniem usera będzie w tejże właśnie funkcji filtrować
wpisywane sekwencje znaków np wpiszesz literę, to funkcja event
ją wyłapie, wpiszesz skrót klawiaturowy, to funkcja ją wyłapie.
jak do tego doszedłem? ano tak, że odbiłem się od ściany - nie dosłownie - wybaczcie, ja się uczę, tak? ileż można? - jestem sam jak palec :) no dobra - odbiłem się od ściany w następujący sposób
szkielet funkcji event
- krok po kroku - pusta wygląda tak i jak jest pusta to... nic nie zwraca, znaczy zwraca bool :D - to nie jest śmieszne
bool MyQLineEdit::event(QEvent *event)
{
return true;
}
miałem tą funkcję wypełnioną moim warunkiem którego zadanie jest... przerysowanie widgetu na nowo, tak, przerysowałem go i działa jak chcę
bool MyQLineEdit::event(QEvent *event)
{
if(event->type() == QEvent::Paint){
QPaintEvent *ev = static_cast<QPaintEvent*>(event);
MyQLineEdit::paintEvent(ev);
return true;
}
return QLineEdit::event(event);
}
ale idźmy dalej... na końcu tej funkcji, jest magiczne wyjście z wywołaniem tejże funkcji czyli mowa o return QLineEdit::event(event);
i tutaj rozpoczyna się moja zabawa, bo zwracałem domyślną implementację nie połączyłem kropek i walczyłem z czymś innym niż powinienem był walczyć - ale tak to jest jak odkrywa się nieznane... no więc jak zwracałem domyślną implementację, to zwracałem tak naprawdę resztę tego czego nie nadpisałem w warunkach i odnosząc się do klawiatury nie nadpisywałem dwóch warunków QEvent::KeyPress
and QEvent::KeyRelease
- czyli całość powinna wyglądać tak - olewamy mój paint, bo nie o tym tutaj mowa
bool MyQLineEdit::event(QEvent *event)
{
if(event->type() == QEvent::KeyPress){
return true;
}
if(event->type() == QEvent::KeyRelease){
return true;
}
}
więc jak zrobiłem te dwa warunki to nagle okazało się, że klawiatura nie działa - huraaa - jestem w domu - nie nie jestem, bo zaraz zacznie się gorączkowe szukanie w bibliotece, gdzie jest ta klawiatura obsługiwana - zgadniecie? pewnie większość z was zgadnie, ja tak szybko nie zgadłem, bo zanim dopowiedziałem sobie resztę, to upłynęło trochę czasu... i wiecie co? Właśnie tutaj zderzyłem się ze ścianą, przyłożyłem i mnie olśniło... i dopowiedziałem sobie resztę - to tylko moje przypuszczenia - że klawiatura jest obsługiwana na etapie jądra i jak pisałem na początku, że biblioteka przechwytuje wywołania z jądra, więc dlatego nie mogłem napisać obsługi CapsLocka na przemian z Shiftem - bo to robi już za mnie jądro, a biblioteka nie udostępnia fizycznego dostępu do sprzętu... bo i po co? jak już jest obsługiwany. Więc połączyłem kropki i mi wyszło, że biblioteka QKeyEvent służy do tego aby
- wychwycić jakiś znak lub skrót klawiaturowy
- obsłużyć go
- po obsłudze odpalić jakieś zdarzenie
tak, odkrył amerykę powiecie, tak kurde, odkryłem, bo wyobraźcie sobie, że porywacie się na głęboką wodę i nadpisujecie jakiś widget jak ja to robię w tym przypadku, że nadpisuję QLineEdit tworząc własną podklasę tego obiektu no i co dalej? Trzeba go obsłużyć i po to właśnie są te funkcje event
i reszta czyli jaki wyłania się z tego obrazek? No taki
- Napisałem podklasę QLineEdit, bo nie podoba mi się domyślna implementacja - chodzi o wygląd
- więc jak robię swój wygląd to okazało się, że trzeba zadbać o resztę czyli o klawiaturę i skróty klawiaturowe i jak to całościowo wygląda? no mniej więcej z grubsza tak... to tylko kod pokazowy, nie jakieś tam rozwiązanie
przechwytuję wciśnięcie przez użytkownika kombinacji klawiszy shift + a
and shift + b
- jak przechwycę, to co dalej z tym zrobić? Można to sobie wyobrazić jako "kopiuj" - "wklej"
bool MyQLineEdit::event(QEvent *event)
{
if(event->type() == QEvent::KeyPress){
QKeyEvent *evKey = static_cast<QKeyEvent*>(event);
if(evKey->key() == Qt::Key_A && evKey->modifiers() == Qt::ShiftModifier){
QKeyEvent k(QEvent::KeyPress, 65, Qt::ShiftModifier, "A+shift");
MyQLineEdit::keyPressEvent(&k); //przesyłam wciśniętą kombinację do funkcji keyPressEvent
return true; //po obsłużeniu wypad z funkcji, bo działa w EventLoop
}
if(evKey->key() == Qt::Key_B && evKey->modifiers() == Qt::ShiftModifier){
QKeyEvent k(QEvent::KeyPress, 66, Qt::ShiftModifier, "B+shift");
MyQLineEdit::keyPressEvent(&k); //przesyłam wciśniętą kombinację do funkcji keyPressEvent
return true; //po obsłużeniu wypad z funkcji, bo działa w EventLoop
}
return QLineEdit::event(event);
}
if(event->type() == QEvent::KeyRelease){
return true;
}
return QLineEdit::event(event); //zwrot domyślnej implementacji, która nie jest nadpisana
}
po przechwyceniu którejś kombinacji, obsługa zaczyna się tutaj czyli - co program ma zrobić jak wciśniesz te klawisze? Np wklej... ale jeszcze nie do widgetu
void MyQLineEdit::keyPressEvent(QKeyEvent *event)
{
if(event->device()->type() == QInputDevice::DeviceType::Keyboard){
if(event->type() == QEvent::KeyPress){
if((event->key() == Qt::Key_A) && (event->modifiers() & Qt::ShiftModifier)){
qDebug()<< event->text(); //tutaj po wykryciu szukanej kombinacji pokazuje tekst
}
if((event->key() == Qt::Key_B) && (event->modifiers() & Qt::ShiftModifier)){
qDebug()<< event->text(); //tutaj po wykryciu szukanej kombinacji pokazuje tekst
}
}
}
}
a co dalej jak się puści klawisze? Np wklej do widgetu - np validujesz tekst i jak jest poprawnie zvalidowany, to pokaż go w widgecie...
void MyQLineEdit::keyReleaseEvent(QKeyEvent *event)
{
//tu jeszcze nic nie ma, bo nie wiem ale pomysł jest wyżej - wyświetl bezpośrednio w widgecie
}
to chyba tyle, trochę długi post wyszedł, nie wiem czy komuś będzie chciało się to czytać no... ale napisałem, bo przy szukaniu rozwiązania i zrozumieniu tego, spociłem się nieźle ale chyba rozumiem po co to jest i co tam się dzieje