簡單圖形程式設計的學習(2)---點 Qt實現
分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow
也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!
簡單圖形程式設計的學習(2)---點 (Qt實現)
write by 九天雁翎(JTianLing) -- blog.csdn.net/vagrxie
一、 畫點
在Qt中畫點的函式是QPainter的drawPoint函式,還是放在QPainter體現了Qt決心將所有的繪圖指令放在一個物件中。(除了OpenGL)既然如此,使用方法上和drawText也就差不太多了。
開篇來個最簡單的示例吧,畫點世界的HelloWorld,隨機的點。
這個工程的全部檔案都貼出來,也作為Qt中實現動畫的一種示例:
Main.cpp:
#include <QtGui/QApplication>
#include <QTest>
#include <QTime>
#include "pointwidget.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
PointWidget w;
w.show();
QTime timer;
// 這是能隨機繪點的關鍵,沒有設定此屬性,預設相當於每次Qt都會完整的將上一次的螢幕擦除,
// 新版的Qt中已經沒有了repaint(bool)介面了。
w.setAttribute
while(true)
{
timer.start();
// 呼叫此函式即相當於Windows中的GetMessage,系列函式,包括了tranlate,分發函式等的所有操作
a.processEvents();
w.repaint();
// 此處是控制幀數的關鍵點
while(timer.elapsed() < 33)
{
QTest::qSleep(1);
}
}
}
Pointwidget.h
#ifndef POINTWIDGET_H
#define POINTWIDGET_H
#include <QtGui/QWidget>
#include <QPainter>
#include <QObject>
namespace Ui
{
class PointWidget;
}
class PointWidget : public QWidget
{
Q_OBJECT
public:
PointWidget(QWidget *parent = 0);
~PointWidget();
protected:
void paintEvent(QPaintEvent *event);
//void keyPressEvent(QKeyEvent *event);
//void closeEvent(QCloseEvent *event);
private:
Ui::PointWidget *ui;
};
#endif // POINTWIDGET_H
Pointwidget.cpp
#include "pointwidget.h"
#include "ui_pointwidget.h"
PointWidget::PointWidget(QWidget *parent)
: QWidget(parent), ui(new Ui::PointWidget)
{
ui->setupUi(this);
qsrand(time(NULL));
}
PointWidget::~PointWidget()
{
delete ui;
}
void PointWidget::paintEvent(QPaintEvent *event)
{
QPainter painter(this);
for(int i = 0; i < 1000; ++i)
{
int r = qrand() % 255;
int g = qrand() % 255;
int b = qrand() % 255;
QPen pen(qRgb(r,g,b));
painter.setPen(pen);
int x = qrand() % 800;
int y = qrand() % 800;
// 其實核心內容就是呼叫這一個函式而已
painter.drawPoint(x,y);
}
}
同樣還是比較簡單,當然,得首先熟悉Qt的基本機制,其中控制迴圈的方式特別重要,雖然這裡可以使用與Win32 Timer類似的定時器技術來實現這樣簡單的繪製,但是對於幀數的穩定控制還是這樣的程式碼比較可靠,另外,w.setAttribute(Qt::WA_OpaquePaintEvent);一句夠初學者找夠久的了。。。(我就找了很久)
知道這些以後,剩下的也就是一個qrand函式+ drawPoint函式的理解量了。這裡不放截圖了,這麼簡單的東西放個截圖我都覺得沒有意思。
1. 老電視機雪花點的效果:
Main.cpp中用
PointWidget w;
QPalette palette;
palette.setColor(QPalette::Window, QColor(0,0,0));
w.setPalette(palette);
幾行程式碼改變Widget的背景,這裡說明一下,其實這樣改變背景個人感覺屬於Qt中面向物件過頭的一個問題,事實上遠遠複雜於一個簡單的SetBkColor函式,但是Qt將所有與介面顏色相關的東西封在QPalette中,以後同時改變多個屬性的時候會稍微簡單一點(其實也沒有簡單到哪去,多次呼叫SetTextColor,SetBkColor等語句也不見的複雜到哪去)
老電視機雪花效果中每次都需要擦除重繪避免點的疊加所以一下語句註釋掉
// w.setAttribute(Qt::WA_OpaquePaintEvent);
paintEvent實現:
void PointWidget::paintEvent(QPaintEvent *event)
{
QPainter painter(this);
for(int i = 0; i < 1000; ++i)
{
// 老電視機都是白色雪花點
QPen pen(qRgb(255,255,255));
painter.setPen(pen);
int x = qrand() % 800;
int y = qrand() % 800;
painter.drawPoint(x,y);
}
}
完整程式碼就不貼了。
2. 移動的星空:
主要實現程式碼:
PointWidget::PointWidget(QWidget *parent)
: QWidget(parent), ui(new Ui::PointWidget)
{
ui->setupUi(this);
qsrand(time(NULL));
// 初始化星空中的點
for(int i = 0; i < POINT_NUMBER; ++i)
{
marPoint[i].rx() = qrand() % 800;
marPoint[i].ry() = qrand() % 800;
}
}
PointWidget::~PointWidget()
{
delete ui;
}
void PointWidget::paintEvent(QPaintEvent *event)
{
QPainter painter(this);
QPen pen(qRgb(255,255,255));
painter.setPen(pen);
for(int i = 0; i < POINT_NUMBER; ++i)
{
marPoint[i].rx()++;
if(marPoint[i].x() > 800)
{
marPoint[i].rx() = 0;
}
painter.drawPoint(marPoint[i]);
}
}
思路還是與以前的一樣,無非是西安初始化一些點,然後改變其x座標,但是要說明的是,Qt為我們簡化了很多操作,首先,預設情況下,會擦出每一幀,這樣就不用我們手動通過覆蓋上一個點的方式去完成,另外,預設使用了雙緩衝方式顯示圖片(與上個特性其實是統一的。。。。)完全不閃。。。。
二、 小結
一個個簡單的點就能夠構成的效果比本文展示的要多的多,參考以前的文章,因為筆者對Qt的熟悉程度有限,重新實現程式費時費力,並且也不太適應目前所用的QtCreator工具(主要是vi功能弱的吐血,Eclipse的vi模擬就夠差的了,QtCreator雖然原生就帶,但是幾乎還不如不用,還是VS中的ViEmu強大),程式的其他效果及截圖也請參考此係列相關其他文章了:
《簡單圖形程式設計的學習(2)---點 (Windows GDI實現)》
《簡單圖形程式設計的學習(2)---點 (small basic實現)》
write by 九天雁翎(JTianLing) -- blog.csdn.net/vagrxie