20/10/2018
Qt's malesystem er en fundamental og yderst kraftfuld del af Qt-frameworket, der gør det muligt for udviklere at skabe rige og interaktive brugergrænseflader. Systemet er designet til at være enhedsuafhængigt, hvilket betyder, at den samme kode kan bruges til at tegne på skærmen, på en printer eller endda generere PDF-filer. Kernen i dette system er tre centrale klasser: QPainter, QPaintDevice og QPaintEngine. QPainter er den klasse, du som udvikler interagerer mest med; den indeholder alle funktionerne til at tegne alt fra simple punkter og linjer til komplekse polygoner, billeder og tekst. QPaintDevice er en abstraktion over en 2D-overflade, som QPainter kan tegne på, såsom en QWidget eller et QImage. QPaintEngine fungerer som broen mellem de to og oversætter QPainter's kommandoer til enhedsspecifikke instruktioner. Denne arkitektur sikrer en ensartet og fleksibel tegningsproces på tværs af forskellige platforme og enheder.

Grundlæggende om Tegning med QPainter
Al tegning i en Qt-widget foregår typisk inden i en speciel metode kaldet paintEvent(). Denne metode bliver automatisk kaldt af Qt, hver gang widget'en skal genoptegnes, for eksempel når den først vises, dens størrelse ændres, eller en del af den har været dækket og nu er synlig igen. For at begynde at tegne, opretter man en instans af QPainter og passerer en reference til den enhed, man vil tegne på (typisk this, hvis man er inde i en widget-klasse). Alt tegnearbejde skal udføres mellem QPainter's begin() og end() metoder. I moderne Qt C++ er det dog mere almindeligt blot at oprette QPainter-objektet på stakken, hvor dets konstruktør kalder begin() og dets destruktør automatisk kalder end(), når objektet går ud af scope. Dette sikrer korrekt håndtering af ressourcer.
Et simpelt eksempel på strukturen i en paintEvent kunne se således ud:
void MyWidget::paintEvent(QPaintEvent *event) { QPainter painter(this); // Al din tegnekode kommer her painter.drawLine(10, 10, 100, 100); }Tegning af Tekst og Simple Former
QPainter tilbyder en bred vifte af funktioner til at tegne basale grafiske primitiver. For at tegne tekst bruges drawText(). Man kan specificere position, justering og selvfølgelig selve teksten. For at style teksten skal man først konfigurere QPainter med en QFont og en QPen.
At tegne simple former er lige så ligetil. drawPoint() tegner et enkelt pixel, drawLine() tegner en linje mellem to punkter, og drawRect() tegner et rektangel. Disse funktioner danner grundlaget for mere komplekse grafiske operationer.
Styling med QPen og QBrush
For at kontrollere udseendet af de former, du tegner, bruger du to vigtige hjælpeklasser: QPen og QBrush. Disse klasser definerer henholdsvis stregen (omridset) og fyldet af en form.

Kontrol over Stregen med QPen
En QPen bruges til at tegne linjer og kanterne på former. Den har tre primære egenskaber, du kan kontrollere: farve, bredde og stil.
- Farve: Sættes med en
QColor. Du kan bruge foruddefinerede farver somQt::redeller definere dine egne med RGB- eller hex-værdier. - Bredde: En heltalsværdi, der angiver tykkelsen på stregen i pixels.
- Stil: Definerer, hvordan linjen skal se ud. Dette kan være en solid linje, en stiplet linje, en prikket linje og meget mere.
Nedenstående tabel viser nogle af de mest almindelige pen-stile, der er tilgængelige i Qt.
| Konstant | Beskrivelse |
|---|---|
Qt::SolidLine | En heltrukken linje. Dette er standard. |
Qt::DashLine | En stiplet linje. |
Qt::DotLine | En prikket linje. |
Qt::DashDotLine | En linje med skiftevis streger og prikker. |
Qt::CustomDashLine | Et brugerdefineret mønster af streger og mellemrum. |
Fyld af Former med QBrush
En QBrush definerer, hvordan det indre af en lukket form (som et rektangel eller en ellipse) skal udfyldes. En brush kan være en solid farve, et mønster eller en gradient.
- Farve: Ligesom med
QPen, kan du angive en solid farve medQColor. - Stil: Qt tilbyder en række foruddefinerede mønstre, såsom vandrette linjer (
Qt::HorPattern), diagonale kryds (Qt::DiagCrossPattern) og forskellige tætheder af prikker. - Gradient: For mere avancerede effekter kan en brush indeholde en gradient (
QLinearGradient,QRadialGradient,QConicalGradient), der skaber en glidende overgang mellem to eller flere farver.
Når du har konfigureret din pen og brush, anvender du dem på din QPainter-instans med setPen() og setBrush(). Alle efterfølgende tegneoperationer vil bruge disse indstillinger, indtil du ændrer dem igen.
Avancerede Former og Stier
Udover de simple former, giver Qt mulighed for at tegne mere komplekse figurer. Du kan tegne ellipser, cirkeludsnit (pies), akkorder og polygoner med dedikerede funktioner. For ultimativ kontrol og fleksibilitet kan du bruge klassen QPainterPath. En QPainterPath er en container for en sekvens af tegneoperationer, som kan genbruges og manipuleres som et enkelt objekt. Du kan bygge en sti ved at tilføje linjer, rektangler, ellipser og endda komplekse Bézier-kurver.

En Bézier-kurve er en matematisk defineret kurve, der er ekstremt nyttig i computergrafik til at skabe glatte, organiske former. Med QPainterPath kan du definere en sådan kurve ved hjælp af metoden cubicTo(), som tager et startpunkt, to kontrolpunkter og et slutpunkt. Når stien er bygget, tegnes den med et enkelt kald til painter.drawPath(path).
Forbedring af den Visuelle Kvalitet
Antialiasing
Når man tegner diagonale linjer eller kurver på et pixel-baseret display, kan kanterne fremstå takkede eller "pixelerede". For at modvirke dette kan man aktivere antialiasing. Dette er en teknik, der udglatter kanterne ved at tilføje delvist gennemsigtige pixels langs kanten, hvilket skaber en illusion af en glattere overgang. I Qt aktiveres det nemt med et kald:
painter.setRenderHint(QPainter::Antialiasing);Aktivering af antialiasing giver et meget mere professionelt og poleret udseende, men det kan have en lille performance-omkostning.
Gennemsigtighed og Opacitet
Gennemsigtighed er en vigtig effekt i moderne brugergrænseflader. Du kan opnå dette på to måder. Den første er ved at bruge en QColor med en alfa-værdi (RGBA). En alfa-værdi på 255 er fuldt dækkende, mens 0 er fuldt gennemsigtig. Den anden metode er at indstille en global opacitet for hele QPainter med setOpacity(). Denne metode påvirker alt, der efterfølgende tegnes, og er nyttig til at fade hele grupper af elementer ind eller ud.
Koordinatsystemtransformationer
QPainter tegner i et 2D-koordinatsystem, hvor (0,0) typisk er i øverste venstre hjørne. Nogle gange er det dog lettere at tegne, hvis man kan flytte, rotere eller skalere dette koordinatsystem. QPainter tilbyder metoder som translate(), rotate() og scale() til netop dette. For eksempel, hvis du skal tegne et objekt, der er roteret 45 grader, er det ofte lettere at rotere hele koordinatsystemet 45 grader og derefter tegne objektet, som om det ikke var roteret. Dette er især nyttigt i animationer eller komplekse scener.
Ofte Stillede Spørgsmål (FAQ)
Hvad er `paintEvent`'s rolle?
paintEvent er en hændelseshandler (event handler), der bliver kaldt af Qt-systemet, når en widget skal tegnes. Al kode, der visuelt gengiver widget'ens indhold, skal placeres her for at sikre, at den opdateres korrekt, når vinduet ændrer størrelse, vises eller på anden måde har brug for en visuel opdatering.

Hvad er forskellen på en `QPen` og en `QBrush`?
Kort sagt: `QPen` er til streger, og `QBrush` er til fyld. En `QPen` definerer udseendet af linjer og kanterne på former (farve, tykkelse, stil). En `QBrush` definerer, hvordan det indre område af en lukket form skal udfyldes (med en solid farve, et mønster eller en gradient).
Hvordan kan jeg få min grafik til at se glattere ud?
Den nemmeste måde at forbedre den visuelle kvalitet er ved at aktivere antialiasing. Dette gøres ved at kalde painter.setRenderHint(QPainter::Antialiasing, true); i starten af din `paintEvent`. Dette vil udglatte kanterne på kurver og diagonale linjer.
Er det muligt at tegne uden for en `paintEvent`?
Ja, men det anbefales generelt ikke for widgets. Du kan tegne på andre `QPaintDevice`-objekter, såsom et QImage eller en QPixmap, når som helst. Dette er nyttigt, hvis du vil forberede et billede i baggrunden og derefter blot tegne det færdige billede i din `paintEvent`, hvilket kan forbedre ydeevnen i komplekse scenarier.
Konklusion
Qt's malesystem, med QPainter i spidsen, er et utroligt alsidigt og robust værktøj til at skabe 2D-grafik. Uanset om du udvikler simple brugerdefinerede widgets, datavisualiseringer eller komplekse grafiske editorer, giver Qt dig de nødvendige værktøjer. Ved at mestre koncepterne bag QPainter, QPen, QBrush og QPainterPath åbner du op for en verden af kreative muligheder og kan skabe applikationer med visuelt imponerende og professionelle brugergrænseflader.
Hvis du vil læse andre artikler, der ligner Qt's QPainter: En Guide til 2D-Grafik, kan du besøge kategorien Sundhed.
