Qt實(shí)現(xiàn)圖片移動(dòng)實(shí)例(圖文教程)
這學(xué)期實(shí)訓(xùn)的時(shí)候用MFC做過一個(gè)飛機(jī)大戰(zhàn),很無聊的東西,一直想用Qt做一個(gè),但是在學(xué)校的時(shí)候比較頹,回來看了一下。
首先需要解決的問題是圖片的移動(dòng),怎么說飛機(jī)啊子彈啊都是動(dòng)著的,圖片當(dāng)然要跑起來。
閑話休絮,首先用QtCreator新建一個(gè)QtGui程序,命名為PaintWidget,隨便起的名字,實(shí)驗(yàn)么這不是。
會(huì)生成這三個(gè)文件,其中呢ui不用管,實(shí)驗(yàn)的圖片移動(dòng)需要用的是Event,不是信號(hào)槽,所以u(píng)i就不管了,放了那就是。
第一步要把圖片畫出來,參照《Qt學(xué)習(xí)之路的這段代碼》,不難把圖畫出來,就是重寫paintEvent方法,用QPainter對(duì)象來畫圖。
void PaintedWidget::paintEvent(QPaintEvent *event)
{
QPainter painter(this);
QPixmap pixmap("Cat.png");
QBitmap bitmap("Cat.png");
painter.drawPixmap(10, 10, 128, 128, pixmap);
painter.drawPixmap(140, 10, 128, 128, bitmap);
QPixmap pixmap2("Cat2.png");
QBitmap bitmap2("Cat2.png");
painter.drawPixmap(10, 140, 128, 128, pixmap2);
painter.drawPixmap(140, 140, 128, 128, bitmap2);
}
這是他的結(jié)果
問題是如何使用圖片資源:
在《C++ GUI Qt4 編程 (第二版)》這本書中有例子,直接搜這本書的源代碼,在src\chap04有發(fā)現(xiàn),原來Qt引用資源是用的資源文件這個(gè)東西,是一個(gè)xml,QtCreator中很方便管理。
首先是在項(xiàng)目中添加文件,選擇Qt的資源文件:
因?yàn)橐院罂赡苡泻芏鄨D片,所以我在工程目錄下新建了img這么個(gè)文件夾來存放圖片。
生成的資源文件里面有個(gè)添加前綴,這個(gè)是qt中引用資源需要用的,后面再說,添加文件不用啰嗦了。
為了方便說明,先把源代碼發(fā)上來
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QtGui>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
protected:
void paintEvent (QPaintEvent *event);
void mouseMoveEvent(QMouseEvent *event);
void keyPressEvent(QKeyEvent *event);
private:
Ui::MainWindow *ui;
QPixmap *catImg;
QRect *catImgRect;
protected:
int shrinkMultiple;
int speed;
};
#endif // MAINWINDOW_H
其中 QPixmap*catImg;就是圖片對(duì)象的指針,因?yàn)槲业膱D片是一直貓,所用就起了這么個(gè)名字。
QRect*catImgRect;是這個(gè)圖片的矩形信息,以為圖片移動(dòng)的時(shí)候圖片的x,y坐標(biāo)的值會(huì)改變,矩形信息會(huì)改變,而繪圖函數(shù)里面有個(gè)根據(jù)矩形信息和圖片指針繪制函數(shù)的這么一個(gè)函數(shù)
painter.drawPixmap(*catImgRect,*catImg);
為了方便起見,用catImgRect來存儲(chǔ)這些信息。
而int shrinkMultiple;這個(gè)是圖片的縮放倍數(shù),我貓的圖片有點(diǎn)兒大,把他縮小了一下,當(dāng)然可以沒有
這個(gè)int speed;則是圖片移動(dòng)的像素?cái)?shù)
ok,下面是mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow),
shrinkMultiple(2),speed(10)
{
ui->setupUi(this);
catImg = new QPixmap(":/img/cat.jpg");
int width = catImg->width () / shrinkMultiple;
int height = catImg->height () / shrinkMultiple;
catImgRect = new QRect(10,10,width,height);
QRect rect = this->geometry ();
rect.setWidth (width*4);
rect.setHeight (height*4);
rect.setX (20);
rect.setY (50);
this->setGeometry (rect);
}
void MainWindow::paintEvent (QPaintEvent *event)
{
QPainter painter(this);
painter.drawPixmap(*catImgRect,*catImg);
}
void MainWindow::mouseMoveEvent(QMouseEvent *event)
{
}
void MainWindow::keyPressEvent(QKeyEvent *event)
{
int width = catImgRect->width ();
int height = catImgRect->height ();
switch(event->key ())
{
case Qt::Key_Left:
{
catImgRect->setX (catImgRect->x ()-speed);
break;
}
case Qt::Key_Right:
{
catImgRect->setX (catImgRect->x ()+speed);
break;
}
case Qt::Key_Down:
{
catImgRect->setY (catImgRect->y ()+speed);
break;
}
case Qt::Key_Up:
{
catImgRect->setY (catImgRect->y ()-speed);
break;
}
}
catImgRect->setHeight(height);
catImgRect->setWidth (width);
this->repaint ();
}
MainWindow::~MainWindow()
{
delete catImg;
delete catImgRect;
delete ui;
}
首先看構(gòu)造函數(shù),其中
catImg=new QPixmap(":/img/cat.jpg");
這里是引用資源文件,:/img/cat.jpg,冒號(hào)后面的第一個(gè)斜杠就是剛剛加的前綴。
下面幾行是縮小貓的圖片和初始化貓矩形信息,最后一行是把程序窗口大小設(shè)這為貓圖片大小的4倍。
畫圖函數(shù)就是paintEvent這個(gè)函數(shù),沒什么特別說的,這個(gè)函數(shù)只要是窗口一被重繪就會(huì)調(diào)用的。
關(guān)鍵的移動(dòng)就是重寫
voidMainWindow::keyPressEvent(QKeyEvent*event)
這個(gè)函數(shù),沒什么特別說明的,出了最后一行
this->repaint();
只要是鍵盤被按下,則重繪窗口,如果沒有這個(gè)函數(shù)的話,貓矩形確實(shí)變了,但是圖片的位置沒有變化,除非等到重繪的時(shí)候才會(huì)調(diào)用paintEvent函數(shù),什么時(shí)候重繪的,當(dāng)這部分窗口被遮蔽,最大化最小化,窗口移動(dòng)的時(shí)候(可能還有),repaint函數(shù)的作用是立即重繪,所以圖片就能馬上移動(dòng)了。
圖片移動(dòng)是沒有問題了,關(guān)鍵是不是很流暢,當(dāng)時(shí)用MFC的時(shí)候是用定時(shí)器來解決的這個(gè)問題,Qt中也有定時(shí)器,改天再研究,不過可能會(huì)出現(xiàn)問題,就是窗口閃爍的問題,這個(gè)時(shí)候應(yīng)該會(huì)用到雙緩沖畫圖的技術(shù)。
貼個(gè)最終的圖片
相關(guān)文章
學(xué)習(xí)二維動(dòng)態(tài)數(shù)組指針做矩陣運(yùn)算的方法
這片文章介紹了如何利用二維動(dòng)態(tài)數(shù)組指針做矩陣運(yùn)算,需要的朋友可以參考下2015-07-07淺析Boost智能指針:scoped_ptr shared_ptr weak_ptr
雖然通過弱引用指針可以有效的解除循環(huán)引用,但這種方式必須在程序員能預(yù)見會(huì)出現(xiàn)循環(huán)引用的情況下才能使用,也可以是說這個(gè)僅僅是一種編譯期的解決方案,如果程序在運(yùn)行過程中出現(xiàn)了循環(huán)引用,還是會(huì)造成內(nèi)存泄漏的2013-09-09c語言實(shí)現(xiàn)24小時(shí)制轉(zhuǎn)換為12小時(shí)制示例
這篇文章主要介紹了c語言實(shí)現(xiàn)24小時(shí)制轉(zhuǎn)換為12小時(shí)制示例,需要的朋友可以參考下2014-04-04