Qt 屏保设置

简单总结下在嵌入式arm板中设置屏保的方法:

在Qt中有二个QWSScreenSaver类

这个类的定义如下

定义路径qwindowsystem_qws.h

class Q_GUI_EXPORT QWSScreenSaver

086 {
087 public:
088     virtual ~QWSScreenSaver();
089     virtual void restore()=0;
090     virtual bool save(int level)=0;
091 };

是类class QWSServerPrivate 的成员,在成类中与屏保设置相关的类成员还有

QTime screensavertime;

097     QTimer* screensavertimer;
098     int* screensaverintervals;
099     int screensavereventblocklevel;
100     bool screensaverblockevents;
101     bool screensaverblockevent( int index, int *screensaverinterval, bool isDown );
102     QWSScreenSaver* saver;

void screenSave(int level);

在设置屏保的时候,Qt程序要作为服务端来运行,QWSScreenSaver中的虚函数virtual void restore()和virtual bool save(int level)都是用来重载,

设置在屏保状态的处理在后面的函数中重载,设置恢复屏保的处理在前面的虚函数中执行,为了节省功耗,我在屏保状态下关掉屏幕的背光,在恢复状态下开启背光。

我用这个方法做个简单的测试,能实现屏保时间设置的动态更。说下我这个测试的调试过程

定义了个SCreenSaver类,继承自QWSScreenSaver

类的定义和实现代码如下

#ifndef SCREENSAVER_H
#define SCREENSAVER_H
#include <QWidget>
#include <QWSServer>


class ScreenSaver : public QWSScreenSaver
{
public:
     ScreenSaver();
    virtual void restore();

    virtual bool save(int level);

private:
   int freq;
   int dutycycle;
public slots:
    void ScreenSaver_parameter_changed(int);
   
};

#endif // SCREENSAVER_H

实现文件如下

#include "screensaver.h"
#include <QDebug>
#include <QtCore>
#include    <stdio.h>
#include    <stdlib.h>
#include    <unistd.h>
#include    <sys/ioctl.h>
#include    <sys/stat.h>
#include    <fcntl.h>
#define IOCTL_FREQUENCY 0
#define IOCTL_DUTYCYCLE 1
static int fd;

ScreenSaver::ScreenSaver()
    :QWSScreenSaver()
{
//    window=new QMainWindow();


    qDebug()<<"Inlize";

    QSettings *readini = new QSettings("/home/config.ini", QSettings::IniFormat, 0); //初始化读取当前背光值,并存储
    readini->beginGroup("backlight");
     dutycycle=readini->value("backlight_duty").toInt();
     qDebug("dutycycle=%d",dutycycle);
    readini->endGroup();
    delete readini;

     freq= 6500;

}

void ScreenSaver::restore()
{
    qDebug("enter screen restore");
     //open pwm
    if((fd=open("/dev/pwm9",O_RDWR)) < 0)
    {
        printf("open device gptimer8 error\n");
       exit(1);// close();
    }

    printf("The frequecy is %d Hz\n",freq);
    printf("The duty cycle is %d percent\n",dutycycle);

    ioctl(fd,IOCTL_FREQUENCY,freq);
    ioctl(fd,IOCTL_DUTYCYCLE,dutycycle);
     ::close(fd);
}
bool ScreenSaver::save(int level)
{
   //close pwm  反逻辑

    if((fd=open("/dev/pwm9",O_RDWR)) < 0)
    {
        printf("open device gptimer8 error\n");
       exit(1);// close();
    }

    printf("The frequecy is %d Hz\n",freq);
    printf("The duty cycle is 90\n");

    ioctl(fd,IOCTL_FREQUENCY,freq);
    ioctl(fd,IOCTL_DUTYCYCLE,100);
     ::close(fd);

    qDebug()<<"window show";
            return true;

 

}


void ScreenSaver::ScreenSaver_parameter_changed(int interval)
{
    QWSServer::setScreenSaverInterval(interval*1000);
    // ignore the key/mouse event that turns on the screen

}

屏保设置还需要做一些其他的设置。

我创建一个另外两个类,Input和mainwindow,

mainwindow类的定义如下

class mainwindos : public QMainWindow
{
    Q_OBJECT
public:
    explicit mainwindos(QWidget *parent = 0);
    QPushButton *button;
    QPushButton *screensaver_set;
    Input *time_set;
    test *tes;
    ScreenSaver *saver;
    QPushButton *mousecalibration;
    Calibration cal;
signals:
   
public slots:
    void screeasaver_time_set();
    void mouseclibration_set();
};

其中定义了两个成员函数,saver和time_set,是SCreenSaver的一个对象,time_set是个输入窗口,输入时间,是用来更改屏保的饿时间间隔,

在mainwindow的构造函数中对屏保进行了设置

 saver = new ScreenSaver;
    QWSServer::setScreenSaver((QWSScreenSaver *)saver);
    QWSServer::setScreenSaverInterval(10000);//读配置文件得出初始值
    QWSServer::screenSaverActivate(true);
//    int blocklevel = 1;

 //   QWSServer::setScreenSaverBlockLevel( blocklevel );

我开始犯了个错误所以这个程序调了很长时间,我在mainwindows的实现函数中定义了个连接

connect(time_set,SIGNAL(saver_interval(int)),saver,SLOT(ScreenSaver_parameter_changed(int)));

结果一直报错mainwindos.cpp:46: 错误:no matching function for call to 'mainwindos::connect(Input*&, const char [21], ScreenSaver*&, const char [36])'

我一直没意识到,以为只要是Qt中的类都是可以这样用这样的信号槽方式通信,我又建立个类继承自QWidget,专门用来接收输入窗口输入的数据,

 connect(time_set,SIGNAL(saver_interval(int)),tes,SLOT(ScreenSaver_parameter_changed(int)));

结果正常,我才查了下QWSScreenSaver的定义,上面已经贴出。看信号槽方式不能实现时间立即更新了,就开始考虑用进程间通信的方式,但是那个显然比较麻烦,后来在同学的帮忙下,我直接在Input的类的数只输入槽函数中修改时间间隔,避免了时间参数传递的困扰

void Input::button_click_slot()
{
    QPushButton *buttontem=qobject_cast<QPushButton *>(sender());
    if(buttontem==ui->pushButton)
    {
        number++;

    }
    else
    {
        number=buttontem->text().toInt();
    }
    qDebug("num=%d",number);
    QWSServer::setScreenSaverInterval(number*1000);
    emit saver_interval(number);
}

如果注意到哪句话在程序的任何地方都可以用就不会为时间参数传递伤脑筋了。

我还在网上看见一些别人的屏保的程序的方法:

觉得也很可行

参考网址http://qtcn.org/bbs/read-htm-tid-38469-page-2.html

http://blog.chinaunix.net/uid-27170912-id-3305962.html

那就去重载 bool QApplication::qwsEventFilter ( QWSEvent * event ) 这个函数

重载的方法基本上就是下面这个样子
application.h

复制代码
  1. #ifndef APPLICATION_H
  2. #define APPLICATION_H
  3. #include <QApplication>
  4. #include <QDebug>
  5. class Application : public QApplication
  6. {
  7. public:
  8.     Application(int & argc, char ** argv);
  9.     bool notify(QObject *, QEvent *);
  10.     bool qwsEventFilter(QWSEvent * event);
  11. };
  12. #endif // APPLICATION_H


application.cpp

复制代码
  1. #include "application.h"
  2. Application::Application(int &argc, char **argv):
  3.     QApplication(argc,argv)
  4. {
  5. }
  6. bool Application::notify(QObject *obj, QEvent *e)
  7. {
  8.     //do something
  9.     return QApplication::notify(obj,e);
  10. }
  11. bool Application::qwsEventFilter(QWSEvent *event)
  12. {
  13.     //do something
  14.     return QApplication::qwsEventFilter(event);
  15. }


main.cpp

复制代码
  1. #include "application.h"
  2. #include "mainwindow.h"
  3. int main(int argc, char *argv[])
  4. {
  5.     Application a(argc, argv);
  6.     MainWindow w;
  7.     w.show();
  8.     return a.exec();
  9. }
小弟按照cutemmll大侠的做法,确实可抓到所有鼠标事件

bool Application::notify(QObject *obj, QEvent *e)
{
  if(e->type() == QEvent::MouseButtonPress)
  {
    //do something
  }
  return QApplication::notify(obj,e);
}

  1. class Application : public QApplication
  2. {
  3. public:
  4.     Application(int & argc, char ** argv);
  5.     bool notify(QObject *, QEvent *);
  6.     void setWindowInstance(MainWindow* wnd);
  7. private:
  8.     MainWindow* window; //保存一个你窗体的指针
  9. };

  10. cpp
复制代码
  1. Application::Application(int &argc, char **argv)
  2.     :  QApplication(argc,argv)
  3.     ,  window(0)
  4. {
  5. }
  6. void Application::setWindowInstance(MainWindow *wnd)
  7. {
  8.     window = wnd;
  9. }
  10. bool Application::notify(QObject *obj, QEvent *e)
  11. {
  12.     if(e->type() == QEvent::MouseMove)
  13.     {
  14.         if(window)
  15.         {
  16.             window->doSomething(); //调用你窗体相应的函数
  17.         }
  18.     }
  19.     return QApplication::notify(obj,e);
  20. }

  1. int main(int argc, char *argv[])
  2. {
  3.     Application app(argc, argv);
  4.     MainWindow w;
  5.     w.show();
  6.     app.setWindowInstance(&w);
  7.     return app.exec();
  8. }

    另一种方式是重写QAPPLICATION的 函数,实现对整个程序的监听。
    一下来源于 http://qtcn.org/bbs/read-htm-tid-38469-page-2.html
    自己测试过,工程太大,不方便传上。
     
    头文件:

    class Application : public QApplication
    {
    public:
        Application(int & argc, char ** argv);
        bool notify(QObject *, QEvent *);
        void setWindowInstance(MainWindow* wnd);
    private:
        MainWindow* window; //保存一个你窗体的指针
    };
    CPP:
    Application::Application(int &argc, char **argv)
        :  QApplication(argc,argv)
        ,  window(0)
    {
    }
    void Application::setWindowInstance(MainWindow *wnd)
    {
        window = wnd;
    }
    bool Application::notify(QObject *obj, QEvent *e)
    {
        if(e->type() == QEvent::MouseMove)
        {
            if(window)
            {
                window->doSomething(); //调用你窗体相应的函数
            }
        }
        return QApplication::notify(obj,e);
    }
     
    main.cpp
    int main(int argc, char *argv[])
    {
        Application app(argc, argv);
        MainWindow w;
        w.show();
        app.setWindowInstance(&w);
        return app.exec();
    }
     
    还有一种就是EventFilter方式:没去试
    重载 bool QApplication::qwsEventFilter ( QWSEvent * event ) 这个函数
    #ifndef APPLICATION_H
    #define APPLICATION_H
    #include <QApplication>
    #include <QDebug>
    class Application : public QApplication
    {
    public:
        Application(int & argc, char ** argv);
        bool notify(QObject *, QEvent *);
        bool qwsEventFilter(QWSEvent * event);
    };
    #endif // APPLICATION_H
     
    #include "application.h"
    Application::Application(int &argc, char **argv):
        QApplication(argc,argv)
    {
    }
    bool Application::notify(QObject *obj, QEvent *e)
    {
        //do something
        return QApplication::notify(obj,e);
    }
    bool Application::qwsEventFilter(QWSEvent *event)
    {
        //do something
        return QApplication::qwsEventFilter(event);
    }
     
    main.pp:

    #include "application.h"
    #include "mainwindow.h"
    int main(int argc, char *argv[])
    {
        Application a(argc, argv);
        MainWindow w;
        w.show();
        return a.exec();
    }
  9. 网上的这些代码主要是重载QApplication的角度来实现,我还没顾上测试

你可能感兴趣的:(application,Class,input,qt,button,Signal)