QString currentMovieDirectory;
QLabel *movieLabel;
QMovie *movie;
QToolButton *openButton;
QToolButton *playButton;
QToolButton *pauseButton;
QToolButton *stopButton;
QToolButton *quitButton;
QToolButton *speedPlusButton;
QToolButton *speedMinusButton;
QSpinBox *speedSpinBox;
QSlider *frameSlider;
QLabel *frameLabel;
QLabel *speedLabel;
QGridLayout *controlsLayout;
QHBoxLayout *buttonsLayoutAll;
QGridLayout *buttonsLayout;
QVBoxLayout *mainLayout;
下面进入movieplayer.cpp文件,首先设置窗口属性,这里将窗口的大小设为500*500: setWindowTitle(tr("Movie"));
resize(500,500);
设置movie的缓存模式,这里我们要求当文件播放一遍后返回重新播放,所以使用CacheAll模式: movie = new QMovie(this);
movie->setCacheMode(QMovie::CacheAll);
设置movieLabel,这里我们设置缩放的方式为Expanding,这样可以按照原来文件的尺寸做出较好的调整,不至于被截取部分: movieLabel=new QLabel(tr("NO movie loaded"));
movieLabel->setAlignment(Qt::AlignCenter);
movieLabel->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding);
movieLabel->setBackgroundRole(QPalette::Dark);
movieLabel->setAutoFillBackground(true);
以下是两个函数: currentMovieDirectory="movies";
createControls();
createButtons();
在createControls中,注意几个控件的布局要协调:
void movieplayer::createControls()
{
frameLabel=new QLabel(tr("Current frame:"));
frameLabel->setAlignment(Qt::AlignVCenter|Qt::AlignRight);
frameSlider=new QSlider(Qt::Horizontal);
frameSlider->setTickInterval(1);
speedLabel=new QLabel(tr("Speed:"));
speedLabel->setAlignment(Qt::AlignVCenter|Qt::AlignRight);
speedSpinBox=new QSpinBox;
speedSpinBox->setRange(1,500);
speedSpinBox->setValue(movie->speed());
speedSpinBox->setSuffix(tr("%"));
controlsLayout=new QGridLayout;
controlsLayout->addWidget(frameLabel,1,0);
controlsLayout->addWidget(frameSlider,1,1,1,3);
controlsLayout->addWidget(speedLabel,1,4);
controlsLayout->addWidget(speedSpinBox,1,5);
}
在cteateButtons之前要把图标文件xxx.png添加到生成的.pro根目录中去,然后右击movie,添加新文件,Qt资源文件,定位到根文件夹,命名为button,系统会自动生成button.qrc文件。点击button.qrc文件,在最下角前缀输入框将“/new/prefix1”改成“/”,然后点击添加,添加文件,将几个png文件选择添加,此时再点击button.qrc就会看到png文件已经添加进来。 然后就是button控件的创建。这里调用QPixmap将图片添加到button中,设置控件固定大小为25*25,setAutoRaise可以将button的外边框去除在鼠标滑过该button时会有浮出效果显示边框,这个效果比较好看。setToolTip函数可以使鼠标放在控件上时提示该控件可以执行的操作,然后调用信号槽做响应的Open(),Start()等操作。 值得注意的是,play和pause控件将重叠在同一位置。
void movieplayer::createButtons()
{
QSize iconSize(25,25);
QPixmap icon1(":/use_001.png");
openButton=new QToolButton;
openButton->setIcon(icon1);
openButton->setAutoRaise(true);
openButton->setIconSize(iconSize);
openButton->setToolTip(tr("Open a file"));
connect(openButton,SIGNAL(clicked()),this,SLOT(Open()));
QPixmap icon2(":/use_007.png");
playButton=new QToolButton;
playButton->setIcon(icon2);
playButton->setIconSize(iconSize);
playButton->setAutoRaise(true);
playButton->setToolTip(tr("Play"));
connect(playButton,SIGNAL(clicked()),this,SLOT(Start()));
QPixmap icon3(":/use_008.png");
pauseButton=new QToolButton;
pauseButton->setIcon(icon3);
pauseButton->setAutoRaise(true);
pauseButton->setIconSize(iconSize);
pauseButton->setToolTip(tr("Pause"));
pauseButton->setVisible(false);
connect(pauseButton,SIGNAL(clicked()),this,SLOT(Pause()));
QPixmap icon4(":/use_002.png");
stopButton=new QToolButton;
stopButton->setIcon(icon4);
stopButton->setAutoRaise(true);
stopButton->setIconSize(iconSize);
stopButton->setToolTip(tr("Stop"));
connect(stopButton,SIGNAL(clicked()),this,SLOT(Stop()));
speedMinusButton=new QToolButton;
QPixmap icon5(":/use_005.png");
speedMinusButton->setIcon(icon5);
speedMinusButton->setAutoRaise(true);
speedMinusButton->setIconSize(iconSize);
speedMinusButton->setToolTip(tr("Speed up"));
connect(speedMinusButton,SIGNAL(clicked()),this,SLOT(SpeedDown()));
speedPlusButton=new QToolButton;
QPixmap icon6(":/use_011.png");
speedPlusButton->setIcon(icon6);
speedPlusButton->setAutoRaise(true);
speedPlusButton->setIconSize(iconSize);
speedPlusButton->setToolTip(tr("Speed down"));
connect(speedPlusButton,SIGNAL(clicked()),this,SLOT(SpeedUp()));
buttonsLayout=new QGridLayout;
buttonsLayout->addWidget(speedMinusButton,0,0);
buttonsLayout->addWidget(playButton,0,1);
buttonsLayout->addWidget(pauseButton,0,1);
buttonsLayout->addWidget(speedPlusButton,0,2);
buttonsLayout->addWidget(stopButton,0,3);
buttonsLayoutAll=new QHBoxLayout;
buttonsLayoutAll->addWidget(openButton);
buttonsLayoutAll->addStretch();
buttonsLayoutAll->addLayout(buttonsLayout);
buttonsLayoutAll->addStretch();
}
接下来利用layout完成整个布局,以下是完整的构造函数:
movieplayer::movieplayer(QWidget *parent) :
QWidget(parent)
{
setWindowTitle(tr("Movie"));
resize(500,500);
movie = new QMovie(this);
movie->setCacheMode(QMovie::CacheAll);
movieLabel=new QLabel(tr("NO movie loaded"));
movieLabel->setAlignment(Qt::AlignCenter);
movieLabel->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding);
movieLabel->setBackgroundRole(QPalette::Dark);
movieLabel->setAutoFillBackground(true);
currentMovieDirectory="movies";
createControls();
createButtons();
connect(movie,SIGNAL(frameChanged(int)),this,SLOT(updateFrameSlider()));
connect(movie,SIGNAL(stateChanged(QMovie::MovieState)),this,SLOT(updateButtons()));
connect(frameSlider,SIGNAL(valueChanged(int)),this,SLOT(goToFrame(int)));
connect(speedSpinBox,SIGNAL(valueChanged(int)),movie,SLOT(setSpeed(int)));
mainLayout=new QVBoxLayout;
mainLayout->addWidget(movieLabel);
mainLayout->addLayout(controlsLayout);
mainLayout->addLayout(buttonsLayoutAll);
setLayout(mainLayout);
updateFrameSlider();
updateButtons();
}
中间的信号槽想必不难理解,最后讲调用两个update函数更新控件状态。 接下来先对button控件的槽函数做一下定义,首先是Open(),首先得打开的路径,QFileInfo(fileName).path()将记录第一次打开文件的路径,当打开文件后,movie就开始自动播放:
void movieplayer::openFile(const QString &fileName)
{
currentMovieDirectory=QFileInfo(fileName).path();
movie->stop();
movieLabel->setMovie(movie);
movie->setFileName(fileName);
movie->start();
}
void movieplayer::Open()
{
QString fileName=QFileDialog::getOpenFileName(this,tr("Open a flie"),
currentMovieDirectory);
if(!fileName.isEmpty())
{
openFile(fileName);
pauseButton->setVisible(true);
playButton->setVisible(false);
}
}
Pause():
void movieplayer::Pause()
{
movie->setPaused(true);
playButton->setEnabled(true);
pauseButton->setEnabled(false);
pauseButton->setVisible(false);
playButton->setVisible(true);
}
Start():
void movieplayer::Start()
{
movie->start();
playButton->setEnabled(false);
playButton->setVisible(false);
pauseButton->setEnabled(true);
pauseButton->setVisible(true);
}
Stop():
void movieplayer::Stop()
{
movie->stop();
playButton->setEnabled(true);
pauseButton->setEnabled(false);
pauseButton->setVisible(false);
playButton->setVisible(true);
}
SpeedUp()&SpeedDown(),这里设置Speed的范围是1—500,每按下一次控件增减的量为20:
void movieplayer::SpeedUp()
{
qint32 currentSpeed=movie->speed();
if(currentSpeed<=480)
{
movie->setSpeed(currentSpeed+20);
speedSpinBox->setValue(currentSpeed+20);
}
else
{
movie->setSpeed(500);
speedSpinBox->setValue(500);
}
}
void movieplayer::SpeedDown()
{
qint32 currentSpeed=movie->speed();
if(currentSpeed>20)
{
movie->setSpeed(currentSpeed-20);
speedSpinBox->setValue(currentSpeed-20);
}
else
{
movie->setSpeed(1);
speedSpinBox->setValue(1);
}
}
这里还有一点要说明,当接受者为movie时,槽函数将调用系统函数,这也是QMovie的功能所在。其实这里的Speed()函数时同样可以调用movie->setSpeed(),只是因为关联控件的考虑才没有用。 下面是槽函数goToFrame,用以关联frameSlider和movie: void movieplayer::goToFrame(int frame)
{
movie->jumpToFrame(frame);
}
最后是update函数,在updateFrameSlider中,首先设定frameSlider的最大值,如果打开的movie存在,将激活除pause外的所有控件:
void movieplayer::updateFrameSlider()
{
bool hasFrame=(movie->currentFrameNumber()>=0);
if(hasFrame)
{
if(movie->frameCount()>0)
frameSlider->setMaximum(movie->frameCount()-1);
else
{
if(movie->currentFrameNumber()>frameSlider->maximum())
frameSlider->setMaximum(movie->currentFrameNumber());
}
frameSlider->setValue(movie->currentFrameNumber());
}
else
frameSlider->setMaximum(0);
frameLabel->setEnabled(hasFrame);
frameSlider->setEnabled(hasFrame);
speedMinusButton->setEnabled(hasFrame);
speedPlusButton->setEnabled(hasFrame);
stopButton->setEnabled(hasFrame);
}
updateButtons的设定是原来程序里的,这里没有做修改0v0:
void movieplayer::updateButtons()
{
playButton->setEnabled(movie->isValid()&&movie->frameCount()!=1
&&movie->state()==QMovie::NotRunning);
pauseButton->setEnabled(movie->state()!=QMovie::NotRunning);
pauseButton->setCheckable(movie->state()==QMovie::NotRunning);
stopButton->setEnabled(movie->state()!=QMovie::NotRunning);
}
经过上述步骤,就可以得到开头所示的gif播放器了,加载了文件如下: 如果要生成可执行文件,就要将默认的debug改为release,就可以生成了: 在windows中往往需要将安装目录下/bin中的libgcc_s_dw2-1.dll、mingwm10.dll、QtCore4.dll、QtGui4.dll一并拷入exe所在的目录,这样就可以点击exe直接执行啦!! 最后,如果你嫌默认的exe图标不够好看,你也可以将其替换成你喜欢的图形。这里需要强调,在之前的button中,图像文件可以是png、ico、jpeg等格式的,但是在这里,系统只接受ico格式的! 将可执行文件替换成自己想要的图标需要以下几个步骤: 1、将你的ico文件放入根目录,我用的是i.icon; 2、右击movie添加新文件,概要,文本文件,选择路径并命名为app.rc; 3、打开app.rc,只添加一条指令为 IDI_ICON1 ICON DISCARDABLE "i.ico"
4、构建文件 5、打开pro文件,在最尾处添加 RC_FILE=
app.rc
6、重新构建发布,就可以得到新的exe图标: 这个简单的gif播放器来源于Qt自带的example中,通过从头到尾自己的创建,对于熟练掌握Qt的一些基本操作还是很有好处的,最后附上生成文件,也算是个小软件了吧,希望大家可以一起学习,共同进步! Eggif 1.0:http://pan.baidu.com/share/link?shareid=3500459208&uk=3641520234 原文始发于微信公众号(汇编语言):给QT新手的练手项目——基于QT的GIF播放器
免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论