QPaintEvent - powtarza się 4 razy

0

Cześć,
Mam dziwny problem.
Utworzyłem pusty projekt, po prostu "New QT Widget Application" i jak zaimplementuje taki kod:

void MainWindow::paintEvent(QPaintEvent *e)
{
    cout << 1 << endl;
}

Otrzymuję taki rezultat:
1
1
1
1

Wygląda to tak jakby funkcja paintEvent była automatycznie wykonana 4 razy. Dlaczego?
Czy nie mogę tego zmienić, aby zawsze wykonywała się tylko raz?

Próbowałem czytać instrukcję ale nie mogę znaleźć nic na ten temat.

Za pomoc z góry dziękuję i pozdrawiam

0

Metoda paintEvent może być wywołana wielokrotnie dla różnych obszarów kontrolki. Sprawdź jakie wartości zwraca metoda rect() obiektu QPaintEvent w kolejnych wywołaniach.

0

Problemem jest nadpisywanie paintEvent z QMainWindow.
QMainWindow pełni rolę kontrolera i pojemnika na inne widgety i w związku z tym może poajwić się kilka wydarzeń powodujących odrysowanie.

0

Dzięki za odpowiedź.
Rzeczywiście ta funkcja gdzieś się z automatu odpala przy każym odświerzeniu okna, czyli nawet jak chwycę okno i je np. przeniosę w inn miejsce ekranu to automatycznie ta funkcja wykonuje się wielokrotnie.
Rozumiem - a raczej przyjmuję - że tak musi być.
A o co chodzi z metodą rect() to nie mam pojęcia, wiem tylko, że to ma jakiś związek z rysowaniem prostokątów, ale jaki to ma związek z moim przypadkiem? Może taki, że główne okno programu jest prostokątem? Ale myślałem, że okno się generuje gdzieś jeszcze "wyżej", bo przecież nawet gdy w klasie MainWindow w ogóle nie utworzę funkcji paintEvent, to okno programu i tak się pojawia?

Jak będę miał chwilę to spróbuję obczaić o co biega, ale się boję w to wgłębiać, bo z mojego klikutygodniowego doświadczenie wiem, że takie wgłębianie się często pochłania wiele czasu, a człowiek i tak wychodzi z tego jeszcze bardziej zamotany ze spotęgowaną ilością pytań :)
W każdym razie dzięki za pomoc

0
  1. Czytaj dokumentację. metoda rect jest jasno udokumentowana
  2. Już ci pisałem, że dla QMainWindow nie powinno się nadpisywać metody paintEvent.
  3. Stwórz nową klasę dziedziczącą po QWidget i jej instancję ustaw jako cetralWidget.
0

:)
Hej dzięki za pomoc.
Wiesz co? Jestem wciąż jeszcze nowicjuszem w programowaniu ogólnie i z góry przepraszam jeżeli zadaje głupie pytania.

Rozumiem, że w tym miejscu gdzie dla instancji tej domyślnej paintEvent podaję (this), to w tym miejscu dla mojej nowej niezależnej funkcji malowania powinienem podać (centralWidget).
Powiem szczerze, że już wcześniej tego próbowałem i nie mogłem się uporać z tym, albo mi się nie "malowało nic", albo nie tam gdzie trzeba, albo błędy wyskakiwały.

Próbowałem tego, gdyż chciałem aby moje malowanie odbywało się w mniejszej ramce - tzn. nie bezpośrednio w głównym oknie, ale w utworzonym mniejszym okienku (bodajże QVBoxWidget, lub coś takiego). Ogólnie trochę pogubić się można. Bo jak tworzysz nową ramkę to ona domyślnie tworzy się jako QWidget (z tego co pamiętam, nie mam teraz przed sobą QT), ale w jakimś tutorialu, gdzie koleś malował właśnie w takim mniejszym oknie, to najpierw zamieniał (robił "Promote to...") ten QWidget na QVBoxWidget. Już nie pamiętam dlaczego tak robił, niestety też nie mogę się dogrzebać już do tego tutoriala.

Ale czasami jak się wróci do tematu po pewnym czasie to mózg podaje nowe pomysły i rozwiązania, więc jak wróce do domu to spróbuję przerobić jeszcze raz ten paintEvent na jakąś niezależną funkcję malowania. Może mi się uda tym razem.

Dzięki za odpowiedź.

0

Metoda rect() z klasy QPaintEvent zwraca współrzędne obszaru, który jest odrysowywany. Nie zawsze odrysowywane jest całe okno, czasem tylko fragment.

Tak jak pisał Marek, utwórz własny widget z przeciążoną metodą paintEvenet:

  1. Utwórz klasę C++ np. MyWidget, która dziedziczy po QWidget (najlepiej przy pomocy Qt Creatora, doda do klasy niezbędne deklaracje).
  2. Zdefiniuj przeciążoną metodę paintEvent w klasie MyWidget.
  3. W formularzu okna umieść kontrolkę Widget
  4. Korzystając z menu kontekstowego, zmień klasę kontrolki Widget na MyWidget (użyj opcji zastąp).

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