Explicarea detaliată desen pe widget-ul prin intermediul qpaintevent
Datorită numărului mare de întrebări similare de la începători pentru a utiliza QPainter. și oamenii întreabă „cum să atragă ceva din propria lor pe widget“, mă înscriu pentru conceptele de bază de desen.
Să începem cu regula principală - pentru a desena pe widget puteți suprascrie metoda paintEvent (QPaintEvent *).
Motivul pentru imperative retrasarea care codul rulează în această funcție, va fi lansat de fiecare dată când este necesar pentru a aspira aspectul widget-ului. Redesenați, de fapt, trebuie să se întâmple foarte des - atunci când modificați geometria widget-ului (de exemplu, ne-am întins pe fereastră, și cu ea întins widget nostru), atunci când widget-ul este acoperit / perestaot_perekryvatsya / izmenilos_perekryvanie alte widget-uri - acestea sunt principalele motive pentru Revopsiți automată de apel.
Apropo, vopsi automată de apel nu este întotdeauna suficientă, dar ne putem provoca redesenarea prin apelarea de actualizare () metoda pentru widget-ul.
Rezumând, putem spune următoarele: dacă vrem să desenezi ceva pe widget - avem nevoie pentru a crea propriul widget și suprascrie paintEvent (QPaintEvent *) metoda. După aceea, vom crea un obiect al clasei noastre.
1. Noi cream widget nostru, care vă permite să trasați pe tine:
#ifndef QPAINTWIDGET_H
#define QPAINTWIDGET_H
clasa QPaintWidget. QWidget publice
<
Q_OBJECT
publice.
QPaintWidget (QWidget * părinte = 0);
protejat.
anula paintEvent (QPaintEvent *);
>;
QPaintWidget. QPaintWidget (QWidget * părinte). QWidget (părinte)
<
>
anula QPaintWidget. paintEvent (QPaintEvent *) <
QPainter p (aceasta); // Crearea unui nou pictor obiect
p. setPen (QPen (Qt roșu 1. Qt SolidLine) ...); // Setări desen
p. drawLine (0. 0. lățimea (), înălțimea ()); // Desenam linia
>
p.setPen (QPen (Qt :: red, 1, Qt :: SolidLine)); - desen personalizabile. spune mai degrabă că este necesar să se elaboreze un solid de culoare roșie linii 1 pixel.
p.drawLine (0,0, lățime (), înălțimea ()); - trage o linie de la punctul (0,0) (implicit este colțul din stânga sus al widget, dar acest lucru poate fi schimbat) la un punct cu coordonatele (lățime, înălțime).
Ca rezultat, am dobomsya că avem pe widget-ul va atras întotdeauna o linie roșie diagonală.
2. O mică explicație a sistemului de coordonate:
În mod implicit, widget-ul are un sistem de coordonate cu originea în colțul din stânga sus ((0,0)). Axa X îndreptate spre dreapta, axa Y este îndreptată în jos. Cu toate acestea, puteți modifica oricând setWindow funcția () - detalii QtAssistant.
3. Rămâne de a crea un obiect al clasei noastre.
Am creat un proiect cu o fereastră standard de MainWindow. Apoi, el a pus pe aspectul său vertical (dar, desigur, poate fi oricine, la toate - este doar pentru comoditatea de doar un singur mod de a plasa un widget pe un alt widget), care ar pune widget nostru în ea.
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
// clasa nash
#include "qpaintwidget.h"
Spațiu de nume Ui <
MainWindow clasa;
>
clasa MainWindow. QMainWindow publice <
Q_OBJECT
publice.
MainWindow (QWidget * părinte = 0);
protejat.
anula changeEvent (QEvent * e);
privat.
Ui. MainWindow * ui;
// pointer la un obiect al clasei noastre
QPaintWidget * WGT;
>;
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow. MainWindow (QWidget * părinte).
QMainWindow (părinte),
ui (nou Ui. MainWindow)
<
ui -> setupUi (aceasta);
// Crearea widget
WGT = new QPaintWidget (aceasta);
// Și noi l loc în layaut
ui -> verticalLayout -> addWidget (WGT);
>
MainWindow ()
<
// Cleans
WGT -> deleteLater ();
șterge interfața de utilizare;
>
void MainWindow. changeEvent (QEvent * e)
<
QMainWindow. changeEvent (e);
comutator (e -> tip ()) <
caz QEvent. LanguageChange.
ui -> retranslateUi (aceasta);
pauză;
implicit.
pauză;
>
>
Ce se întâmplă? Cozdaotsya widget QPaintWidget * WGT. acesta controlează dimensiunea layout. De îndată ce a avut loc o schimbare de dimensiune, widget-ul se numește metoda paintEvent (QPaintEvent *), în care, în acest widget, trage o linie diagonală în roșu.
Desigur, acest lucru este destul de rar. Dacă vrem într-adevăr ceva să se bazeze pe un widget (de exemplu, grafică), apoi, în curs sunt algoritmi ușor diferite.
5.1. În obiectul nostru widget QImage crea și de a scrie dimensiuni funcția de sincronizare a analiza proceselor la dimensiunile widget-ului. Acest lucru va fi noastră așa-numitele, Back Buffer - tamponul de fond pentru a picta.
5.2. Când avem nevoie de ceva pentru a trage - l-am trage pe această „imagine“. Desenul poate dura o lungă perioadă de timp, poate fi scurt - putem face acest cod într-un fir separat - nu este o problemă. Pur și simplu rezultatul fluxului va QImage obiect să fie pictat tot ceea ce este necesar (de acum va fi calculat și tras - vom claxona procentul de progres).
5.3. Dacă este necesar, vom trage o dată trage tamponul de fundal pentru widget-ul nostru (QImage obiect în cazul în care totul este desenat avem nevoie) metoda QPainter :: drawImage (.) In interiorul functiei paintEvent (QPaintEvent *). Astfel, am dobomsya ceea ce ar fi de redare este netedă și nu descarcă fluxul principal.
Sper ca acest mic ghid va reduce dramatic numărul de întrebări prin tragere la un QPainter.