في هذا الجزء من سلسلة دروس Qt4 سوف نقوم بعمل بعض الرسومات .
متى نحتاج للرسم؟هناك حالات متى أردت انشاء widget من البداية أو رسم مخططات أو حتى صناعة تأثيرات لل widgets ففي جميع هذه الحالات أنت بحاجة الى أن ترسم بإستخدام Qt4 .
إن الفئة Qpainter تعتبر صاحبة الدور الريادي الأكبر للرسم في مكتبة Qt4 , والرسم يكون بواسطة الفئة Qpainter داخل الدالة paintEvent() (في حالى الرسم على widget) .
رسم الخطوط المستقيمة :-
في المثال الأول سوف نرسم بعض الخطوط المستقيمة في مساحة النافذة :-
lines.h
#ifndef LINES_H #define LINES_H #include <QWidget> { Q_OBJECT public: protected: }; #endif The header file. lines.cpp #include 'lines.h' #include <QApplication> #include <QPainter> { } { QPen pen (Qt ::black, 2, Qt ::SolidLine); painter.setPen(pen); painter.drawLine(20, 40, 250, 40); pen.setStyle(Qt::DashLine); painter.setPen(pen); painter.drawLine(20, 80, 250, 80); pen.setStyle(Qt::DashDotLine); painter.setPen(pen); painter.drawLine(20, 120, 250, 120); pen.setStyle(Qt::DotLine); painter.setPen(pen); painter.drawLine(20, 160, 250, 160); pen.setStyle(Qt::DashDotDotLine); painter.setPen(pen); painter.drawLine(20, 200, 250, 200); qreal space = 4; dashes << 1 << space << 5 << space; pen.setStyle(Qt::CustomDashLine); pen.setDashPattern(dashes); painter.setPen(pen); painter.drawLine(20, 240, 250, 240); }
|
لقد قمنا برسم 6 خطوط مستقيمة مختلفة على النافذة .
QPen pen(Qt::black, 2, Qt::SolidLine);
لقد قمنا بإنشاء الكائن QPen حيث أن القلم يكون متصل 'solideLine' وسمكه 2 بكسل ولونه أسود . ويستخدم القلم في رسم الخطوط والحدود الخارجية للأشكال .
QPainter painter(this);
قمنا بغنشاء كائن الرسم الرئيسي QPainter .
painter.drawLine(20, 40, 250, 40);
هنا قمنا برسم أول خط مستقيم حيث أن الوسطاء الأربعة للدالة drawLine يحددون إحداثيات النقطتين على النافذة 'النقطة المطرفة في أعلى يسار النافذة هي (0,0)' .
pen.setStyle(Qt::DashLine);
تقوم هذه الشيفرة بوضع شكل(style) مختلف للقلم .
main.cpp
#include 'lines.h' #include <QDesktopWidget> #include <QApplication> { int x, y; int screenWidth; int screenHeight; int WIDTH = 280; int HEIGHT = 270; screenWidth = desktop->width(); screenHeight = desktop->height(); x = (screenWidth - WIDTH) / 2; y = (screenHeight - HEIGHT) / 2; widget.setGeometry(x, y, WIDTH, HEIGHT); } int main(int argc, char *argv[]) { Lines window; window.setWindowTitle('Lines'); window.show(); center(window); return app.exec(); }
|
Main file.

الألوان :
اللون هو كائن يمثله كل من الأحمر والأخضر والأزرق أو مايسمى نظام الألوان RGB ويمثل كل من الألوان الثلاثة أرقام بحيث تكون من 0 الى 255 في هذا المثال سوف نقوم برسم 9 مربعات ب9 الوان مختلفة :-
colors.h
#ifndef COLORS_H #define COLORS_H #include <QWidget> { public: protected: }; #endif Header file. colors.cpp #include 'colors.h' #include <QApplication> #include <QPainter> { } { painter. setPen(QColor('#d4d4d4')); painter. setBrush(QBrush('#c56c00')); painter.drawRect(10, 15, 90, 60); painter. setBrush(QBrush('#1ac500')); painter.drawRect(130, 15, 90, 60); painter. setBrush(QBrush('#539e47')); painter.drawRect(250, 15, 90, 60); painter. setBrush(QBrush('#004fc5')); painter.drawRect(10, 105, 90, 60); painter. setBrush(QBrush('#c50024')); painter.drawRect(130, 105, 90, 60); painter. setBrush(QBrush('#9e4757')); painter.drawRect(250, 105, 90, 60); painter. setBrush(QBrush('#5f3b00')); painter.drawRect(10, 195, 90, 60); painter. setBrush(QBrush('#4c4c4c')); painter.drawRect(130, 195, 90, 60); painter. setBrush(QBrush('#785f36')); painter.drawRect(250, 195, 90, 60); }
|
لقد رسمنا تسعة مستطيلات بألوان مختلفة وألوان حدودها هو الرمادي.
painter. setBrush(QBrush('#c56c00')); painter.drawRect(10, 15, 90, 60);
|
الفئة QBrush تستخدم لتلوين الأشكال المرسوم بواسطة QPainter و الدالة drawRect تستخدم لرسم المستطسلات حيث أول وسيطين عبارة عن احداثيات النقطة في الركن الأيسر الأعلى من المستطيل ويعبر كل من الوسيط الثالث والرابع عن عرض وارتفاع المستطيل وفي دالة البناء للفئة QBrush عبرنا عن النظام RGB بأرقام بظام الستةعشر.
main.cpp
#include 'colors.h' #include <QDesktopWidget> #include <QApplication> { int x, y; int screenWidth; int screenHeight; int WIDTH = 350; int HEIGHT = 280; screenWidth = desktop->width(); screenHeight = desktop->height(); x = (screenWidth - WIDTH) / 2; y = (screenHeight - HEIGHT) / 2; widget.setGeometry(x, y, WIDTH, HEIGHT); widget.setFixedSize(WIDTH, HEIGHT); } int main(int argc, char *argv[]) { Colors window; window.setWindowTitle('Colors'); window.show(); center(window); return app.exec(); }
|
Main file.

أنماط الصبغ:-
إن الشيفرة المصدرية لهذا المثال سوف تكون مشابهة للمثال السابق ولكن هذه المرة سوف نقوم بصبغ المستطيلات بأنماط صبغ جاهزة توفرها لنا Qt4 :-
brushes.h
#ifndef BRUSHES_H #define BRUSHES_H #include <QWidget> { Q_OBJECT public: protected: }; #endif
|
Header file.
brushes.cpp
#include 'brushes.h' #include <QApplication> #include <QPainter> { } { painter.setPen(Qt::NoPen); painter.setBrush(Qt::HorPattern); painter.drawRect(10, 15, 90, 60); painter.setBrush(Qt::VerPattern); painter.drawRect(130, 15, 90, 60); painter.setBrush(Qt::CrossPattern); painter.drawRect(250, 15, 90, 60); painter.setBrush(Qt::Dense7Pattern); painter.drawRect(10, 105, 90, 60); painter.setBrush(Qt::Dense6Pattern); painter.drawRect(130, 105, 90, 60); painter.setBrush(Qt::Dense5Pattern); painter.drawRect(250, 105, 90, 60); painter.setBrush(Qt::BDiagPattern); painter.drawRect(10, 195, 90, 60); painter.setBrush(Qt::FDiagPattern); painter.drawRect(130, 195, 90, 60); painter.setBrush(Qt::DiagCrossPattern); painter.drawRect(250, 195, 90, 60); }
|
لقد قمنا برسم تسعة مستطيلات بفرش أنماط صبغ مختلفة
painter.setBrush(Qt::HorPattern); painter.drawRect(10, 15, 90, 60);
|
لقد قمنا برسم مستطيل وصبغه بنمط خاص حيث أن Qt::HorPattern ثابت يقوم بتحديد نمط الصبغ بالخطوط الأفقية .
main.cpp
#include 'brushes.h' #include <QDesktopWidget> #include <QApplication> { int x, y; int screenWidth; int screenHeight; int WIDTH = 350; int HEIGHT = 280; screenWidth = desktop->width(); screenHeight = desktop->height(); x = (screenWidth - WIDTH) / 2; y = (screenHeight - HEIGHT) / 2; widget.setGeometry(x, y, WIDTH, HEIGHT); widget.setFixedSize(WIDTH, HEIGHT); } int main(int argc, char *argv[]) { Brushes window; window.setWindowTitle('Brushes'); window.show(); center(window); return app.exec(); }
|
Main file.
Figure: أنماط الصبغ
الدونة :
في هذا المثال سوف نقوم برسم الدونة معتمدين على الدوال التي توفرها لنا مكتبة Qt4 :
donut.h
#ifndef DONUT_H #define DONUT_H #include <QWidget> { Q_OBJECT public: protected: }; #endif
|
Header file.
donut.cpp
#include 'donut.h' #include <QApplication> #include <QPainter> { } { painter. setRenderHint(QPainter::Antialiasing); int h = height(); int w = width(); painter. translate(QPoint(w /2, h /2)); for (qreal rot=0; rot < 360.0; rot+=5.0 ) { painter.drawEllipse(-125, -40, 250, 80); painter.rotate(5.0); } }
|
الدونة هو عبارة عن شكل هندسي متقدم وهو يذكرك بخبز الدونة (الخبز المحلى ) ولقد قمنا بإنشائة برسم 72 من القطع الناقص كل منها ملتف بزاوية مختلفة وجميعها لها نفس المركز .
painter.setRenderHint(QPainter::Antialiasing);
سوف نرسم بإستخدام نمط Antialiasing حيث تكون الرسومات أكثر جودة .
int h = height(); int w = width();
|
painter. translate(QPoint(w /2, h /2));
|
قمنا بتحريك مركز تقاطع محوري س و ص الى منتصف لنافذة حيث يصبح منتصف النافذة هي النقطة (0,0) بدلا من الركن الأعلى الأيسر وذلك عن طريق تحريك نظام الإحداثيات بإستخدام الدالة translate .
for (qreal rot=0; rot < 360.0; rot+=5.0 ) { painter.drawEllipse(-125, -40, 250, 80); painter.rotate(5.0); }
|
في عملية التكرار هذه قمنا برسم 72 قطع ناقص مع تغيير زاوية الميل في كل مرة .
main.cpp
#include 'donut.h' #include <QDesktopWidget> #include <QApplication> { int x, y; int screenWidth; int screenHeight; int WIDTH = 350; int HEIGHT = 280; screenWidth = desktop->width(); screenHeight = desktop->height(); x = (screenWidth - WIDTH) / 2; y = (screenHeight - HEIGHT) / 2; widget.setGeometry(x, y, WIDTH, HEIGHT); } int main(int argc, char *argv[]) { Donut window; window.setWindowTitle('Donut'); window.show(); center(window); return app.exec(); }
|
Main file.
Figure: دونة
رسم الأشكال :-
وفرت لك مكتبة Qt4 العديد من الدوال والفئات لرسم أشكال مختلفة وفي هذا المثال سوف نتعرف على البعض منها
shapes.h
#ifndef SHAPES_H #define SHAPES_H #include <QWidget> { Q_OBJECT public: protected: }; #endif
|
Header file.
shapes.cpp
#include 'shapes.h' #include <QApplication> #include <QPainter> #include <QPainterPath> { } { painter. setRenderHint(QPainter::Antialiasing); path1.moveTo(5, 5); path1.cubicTo(40, 5, 50, 50, 99, 99); path1.cubicTo(5, 99, 50, 50, 5, 5); painter.drawPath(path1); painter.drawPie(130, 20, 90, 60, 30*16, 120*16); painter.drawChord(240, 30, 90, 60, 0, 16*180); painter.drawRoundRect(20, 120, 80, 50); painter.drawPolygon(polygon); painter.drawRect(250, 110, 60, 60); QFont font ('Georgia', 55); path2.addText(baseline, font, 'Q'); painter.drawPath(path2); painter.drawEllipse(140, 200, 60, 60); painter.drawEllipse(240, 200, 90, 60); }
|
لقد قمنا برسم 9 أشكال مختلفة
path1.moveTo(5, 5); path1.cubicTo(40, 5, 50, 50, 99, 99); path1.cubicTo(5, 99, 50, 50, 5, 5); painter.drawPath(path1);
|
الفئة QPaintPath تستخد لرسم الأشكال المعقدة واستخدمناها هنا لرسم منحنيات بزير .
painter.drawPie(130, 20, 90, 60, 30*16, 120*16); painter.drawChord(240, 30, 90, 60, 0, 16*180); painter.drawRoundRect(20, 120, 80, 50);
|
لقد قمنا برسم شكل فطيرة و وتر و مستطيل ذو أطراف مقوسة .
painter.drawPolygon(polygon);
|
هنا قمنا برسم شكل مضلع من خمسة نقاط .
QFont font ('Georgia', 55); path2.addText(baseline, font, 'Q'); painter.drawPath(path2);
|
توفر لك مكتبة Qt4 القدرة على رسم مسارات بإستخدام خطوط المحارف .
painter.drawEllipse(140, 200, 60, 60); painter.drawEllipse(240, 200, 90, 60);
|
توفر لك الدالة drawEllipse القدرة على رسم أشكال القطع الناقص والدائرة (حيث أن الدائرة هي حل من القطع الناقص) .
main.cpp
#include 'shapes.h' #include <QDesktopWidget> #include <QApplication> { int x, y; int screenWidth; int screenHeight; int WIDTH = 350; int HEIGHT = 280; screenWidth = desktop->width(); screenHeight = desktop->height(); x = (screenWidth - WIDTH) / 2; y = (screenHeight - HEIGHT) / 2; widget.setGeometry(x, y, WIDTH, HEIGHT); } int main(int argc, char *argv[]) { Shapes window; window.setWindowTitle('Shapes'); window.show(); center(window); return app.exec(); }
|
Main file.

Figure: أشكال
تدرج الألوان :-
وهو إندماج متدرج للضلال من الضوء للضلام أو من لون الى لون آخر .
ولها استخدامات عدة مثل صبغ خلفية نافذة البرنامج وتطبيق بعض التأثيرات ومحاكات الضلال والضوء و.. .
في هذا المثال سوف نرى أنه كيف بوسعنا ان نبرمج الألوان المتدرجة بإستخدام مكتبة Qt4 .
gradients.h
#ifndef GRADIENT_H #define GRADIENT_H #include <QWidget> { public: protected: }; #endif
|
Header file.
gradients.cpp
#include 'gradients.h' #include <QApplication> #include <QPainter> Gradient ::Gradient(QWidget *parent ){ } { grad1.setColorAt(0.1, Qt::black); grad1.setColorAt(0.5, Qt::yellow); grad1.setColorAt(0.9, Qt::black); painter.fillRect(20, 20, 300, 90, grad1); grad2.setColorAt(0.2, Qt::black); grad2.setColorAt(0.5, Qt::red); grad2.setColorAt(0.8, Qt::black); painter.fillRect(20, 140, 300, 100, grad2); }
|
في هذا البرنامج قمنا برسم مستطيلين ومن ثم قمنا بتلوينهم بألوان متدرجة .
grad1.setColorAt(0.1, Qt::black); grad1.setColorAt(0.5, Qt::yellow); grad1.setColorAt(0.9, Qt::black);
|
الألوان في هذا التدرج معرفة بإستخدام نقاط التوقف حيث أن الدالة setColorAt تستخدم لإنشاء نقاط التوقف من خلال مواقعها (من 0 الى 1 حيث 0 بداية التدرج و1 هو نهايته) ولون كل نقطة توقف.
painter.fillRect(20, 20, 300, 90, grad1);
|
قمنا بتعبئة مساحة المستطيل بإستخدام الألوان المتدرجة .
main.cpp
#include 'gradients.h' #include <QDesktopWidget> #include <QApplication> { int x, y; int screenWidth; int screenHeight; int WIDTH = 350; int HEIGHT = 260; screenWidth = desktop->width(); screenHeight = desktop->height(); x = (screenWidth - WIDTH) / 2; y = (screenHeight - HEIGHT) / 2; widget.setGeometry(x, y, WIDTH, HEIGHT); } int main(int argc, char *argv[]) { Gradient window; window.setWindowTitle('Gradients'); window.show(); center(window); return app.exec(); }
|
Main file.
: الألوان المتدرجة
الإنتفاش(الإنتفاخ مع التلاشي)
هذا هو مثالنا الأخير في هذا الدرس الرسم بإستخدام Qt4 . سوف نقوم بإنشاء تأثير يدعى الإنتفاش حيث في هذا المثال نقوم بعرض نص ينموا من وسط النافذة ويتلاشى تدريجيا من بعض النقاط (تأثير مزدج) .
puff.h
#ifndef PUFF_H #define PUFF_H #include <QWidget> { Q_OBJECT public: protected: private: int x; qreal opacity; int timerId; }; #endif في ملف الرأس قمنا بإنشاء مقبضين للأحداث الأول أحداث الرسم والآخر أحداث المؤقت . puff.cpp #include 'puff.h' #include <QApplication> #include <QPainter> #include <QPainterPath> #include <QTimer> #include <iostream> { x = 1; opacity = 1.0; timerId = startTimer(15); } { int textWidth = fm.width(text); painter.setFont(font); if (x > 10) { opacity -= 0.01; painter.setOpacity(opacity); } if (opacity <= 0) { killTimer(timerId); std::cout << 'timer stopped' << std::endl; } int h = height(); int w = width(); painter. translate(QPoint(w /2, h /2)); painter.drawText(-textWidth/2, 0, text); } { x += 1; repaint(); } { x = 1; opacity = 1.0; timerId = startTimer(15); }
|
في دالة البناء قمنا بتهيئة المؤقت بحيث يرسل الحدث كل 15 ملي ثانية .
وفي دالة التقاط أحداث المؤقت قمنا بزيادة حجم الخط بمقدار 1 و إعادة رسم النافذة
if (x > 10) { opacity -= 0.01; painter.setOpacity(opacity); }
|
في حال كان حجم الخط أكبر من 10 نقوم بزيادة الشفافية (إنقاص العتمة) بشكل تدريجي , زيادة بهوت النص .
if (opacity <= 0) { killTimer(timerId); std::cout << 'timer stopped' << std::endl; }
|
في حال أصبح النص شفافابالكامل نقوم بإيقاف المؤقت ونرسل رسالة تعلم بتوقف المؤقت .
main.cpp
#include 'puff.h' #include <QDesktopWidget> #include <QApplication> { int x, y; int screenWidth; int screenHeight; int WIDTH = 350; int HEIGHT = 280; screenWidth = desktop->width(); screenHeight = desktop->height(); x = (screenWidth - WIDTH) / 2; y = (screenHeight - HEIGHT) / 2; widget.setGeometry(x, y, WIDTH, HEIGHT); } int main(int argc, char *argv[]) { Puff window; window.setWindowTitle('Puff'); window.show(); center(window); return app.exec(); }
|
Main file.
 |