1.练习背景
这次的练习也是项目当中实际要用到的一个功能,就是所谓的欢迎界面。
在现在大多数客户端程序中呢,欢迎界面能够起到很大的作用,不只是字面的欢迎,还可以提示一些注意事项,或者是展示跟自家公司相关的广告或产品。
本次练习呢,不涉及页面的展示内容,只是去实现一个欢迎页面自动跳转的功能。
2.所用技术点
实现欢迎页面除了常用的一些信号,窗口类的常用操作之外呢,主要是使用到了定时器和事件过滤器。
3.实现过程
首先、咱们先分析一下大概的需求是什么样的。
欢迎页面一般是展示一些公司的相关的信息或者一些注意事项,然后在几秒之后自动关闭跳转到主页面,并且除了自动跳转还能通过页面上的按钮进行手动关闭。
然后、说一下咱们的实现思路。
通过定时器,实现十秒之后自动跳转,并且还要用事件过滤器,来筛选鼠标离开页面计时器计时,当鼠标进入页面范围时定时器暂停。
下面直接上代码,这次呢,顺便把UI界面也一块贴出来,首先是重点,欢迎页面:
然后是欢迎页面的代码部分:
这里要说一下C++11的一个新特性,就是nullptr关键字,它的用处是当你定义一个指针变量,并暂时又用不到的时候,为避免其成为野指针,将其置为空指针。在C++11之前都是用NULL,但实际上在C++中,NULL是一个宏定义,它的本质是整数0,C++11增加了nullptr关键字,并且nullptr是有类型的,它是nullptr_t类型的变量。这里只是简单介绍一下,有兴趣的朋友可以自己去查找一些相关资料,网上有很多这方面的介绍,非常的详细。不过既然有了新特性,能够使用nullptr还是尽量用nullptr吧。
然后就是重点了,Qt时间过滤器的使用:
简单的来说就是两个步骤,先给你想要监视的目标对象注册时间过滤器,然后就是在监视对象中重写eventFilter函数来处理目标对象的事件。下面代码中已经完成了目标对象时间过滤器的注册(使用installEventFilter函数)。
WelcomePage::WelcomePage(QWidget *parent) :
QWidget(parent),
ui(new Ui::WelcomePage)
{
ui->setupUi(this);
//为各个变量赋初值
_isFinished = false;
_count = 10;
_timer = nullptr;
//将窗口设置为无边框窗口
this->setWindowFlags(Qt::FramelessWindowHint);
//设置窗口的标题
this->setWindowTitle(tr("WelcomePage"));
//绑定按钮的点击信号和相应的槽函数
connect(ui->btn_quit,SIGNAL(clicked(bool)),this,SLOT(closeForm()));
//为以下对象安装时间过滤器
ui->btn_quit->installEventFilter(this);
ui->label_title->installEventFilter(this);
ui->label_msg->installEventFilter(this);
this->installEventFilter(this);
//为按钮添加快捷键
ui->btn_quit->setShortcut(Qt::Key_Enter);
//将按钮设置为默认控件,并让页面启动时的焦点在按钮上
ui->btn_quit->setFocus();
ui->btn_quit->setDefault(true);
}
然后就是重写eventFilter函数,捕获一下咱们想要的捕获的事件,并作出相应的处理。
如果你想做完自己的处理就不进行默认处理了就直接return true;否则return false;,或者想我这样直接交给基类进行处理。
bool WelcomePage::eventFilter(QObject *widget, QEvent *e){
//判断传入对象是否安装了事件筛选器
if(widget == ui->label_title||widget == ui->label_msg||
widget == ui->btn_quit||widget == ui->textEdit_content||widget == this){
//根据事件的类型,执行相应的函数
if(e->type() == QEvent::Enter){
StopTimer();
}
if(e->type() == QEvent::Leave){
StarTimer();
}
}
//其它部件产生的事件则交给基类处理
return QWidget::eventFilter(widget,e);
}
然后就是其他的函数实现,可以好好看一下注释,每一步都写出了相应的注释。
//重载QWidget的closeEvent函数
void WelcomePage::closeEvent(QCloseEvent *e){
//发送自己定义的closing信号,emit的作用是发送信号
emit closing();
//将标识是否结束欢迎页面播放的变量isFinished赋值为ture(表明欢迎页面已经播放完毕)
_isFinished = true;
//执行函数StopTimer,用来停止计时器
StopTimer();
//执行QWidget的closeEvent函数
QWidget::closeEvent(e);
}
void WelcomePage::StarTimer(){
//判断指针_timer是不是空指针
if(_timer==nullptr){
//如果不是,为它分配内存空间
_timer = new QTimer(this);
//连接信号和槽函数
connect(_timer,SIGNAL(timeout()),this,SLOT(timerLoop()));
//启动计时器
_timer->start(1000);
}
}
void WelcomePage::StopTimer(){
//判断_timer是不是空指针
if(_timer!=nullptr){
//如果不是,停止计时器
_timer->stop();
//释放内存空间
delete _timer;
//设置为空指针
_timer = nullptr;
//设置相应的信息,并将相应的信息显示到控件上
QString msg = tr("CountdowmContinue");
onPostMessage(msg);
}
}
void WelcomePage::onPostMessage(QString&msg){
//将传入的信息,显示到控件上,并设置控件为适应内容的大小
ui->label_msg->setText(msg);
ui->label_msg->adjustSize();
//不停的刷新页面,可以避免如果有处理时间较长的事件导致画面像死掉一样
qApp->processEvents();
}
void WelcomePage::closeForm(){
this->close();
}
void WelcomePage::timerLoop(){
//判断计数变量是否为零,如果是则执行closeForm函数
if(_count==0){
closeForm();
}else{
//如果不为零,则将计数变量减1,然后将相应信息显示到控件上
_count--;
QString str = tr("CountdownBefor")+" "+ QString::number(_count) +" "+ tr("CountdownAfter");
onPostMessage(str);
}
}
然后就是欢迎页面后的主页面,没什么特别的功能,把代码贴出来看看就好。
MainWidget::MainWidget(QWidget *parent) :
QWidget(parent),
ui(new Ui::MainWidget)
{
ui->setupUi(this);
}
MainWidget::~MainWidget()
{
delete ui;
}
然后是主函数的实现,
QApplication a(argc, argv);
WelcomePage *wp = new WelcomePage;
wp = new WelcomePage;
wp->show();
wp->StarTimer();
while (!wp->_isFinished)
{
a.processEvents();
}
MainWidget m;
m.show();
return a.exec();
看看运行的效果:
OK,目标达成,可以套用在任何程序的主窗口之前。
也许还有更好的实现方式,不过目前我能想到的就是这样啦,还请各位大佬多多指教。
下面是代码的下载地址:
https://download.csdn.net/download/menger3388/10880347