QT下欢迎页面的自动跳转——事件过滤器(eventFilter)和定时器的应用

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

 

发布了12 篇原创文章 · 获赞 3 · 访问量 4992
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 技术黑板 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览