查看完整版本: [-- qt  屏保 如何捕获全屏的鼠标事件[已经解决] --]

QTCN开发网 -> Qt基础编程 -> qt  屏保 如何捕获全屏的鼠标事件[已经解决] [打印本页] 登录 -> 注册 -> 回复主题 -> 发表主题

gjf123 2011-05-06 17:04

qt  屏保 如何捕获全屏的鼠标事件[已经解决]

目的,捕获在触摸屏任意位置被按下的鼠标事件,不要告诉我重载mousePressEvent,因为当界面上有控件(如按钮)时,触摸到此控件是不会产生mousePressEvent事件的,也不要告诉我把这个控件安装个事件过滤器,因为,当我有很多个控件时,我一个个安装是比较吃力的。
问题,如何得到在触摸屏任意位置被按下的鼠标事件?(即捕获全局的鼠标事件),因为得到这个事件,我就可以在这个事件里,将定时器启动或清零或退出屏保返回主界面等操作了。

多谢各位大侠相助,小弟感激不尽

dbzhang800 2011-05-06 17:15
可以覆盖 QApplication:notify()
可以给 QApplication 安装事件过滤器
....

duduqq 2011-05-06 17:26
估计和系统的API有关吧,
或者你在鼠标的驱动里试试能不能获得这个事件了

gjf123 2011-05-06 18:12
dbzhang800  提供QApplication:notify()这个思路,觉得肯定可行,但对我这个初学者,较难,渴望dbzhang800  写点代码出来,非常感激。duduqq 大侠的指点,我明白,驱动里肯定能捕获的,感激,不过应用层能做的,就不要麻烦驱动了。
继续请求高手详细指点!小弟感激中

sbtree 2011-05-07 00:06
引用第1楼dbzhang800于2011-05-06 17:15发表的  :
可以覆盖 QApplication:notify()
可以给 QApplication 安装事件过滤器
....

这里我有个疑问,当屏幕保护在运行的时候,屏幕保护程序应该应该处在窗口系统的最顶层,通过notify函数触屏消息能被QApplication截获吗?
我在看QCoreApplication::winEventFilter函数的时候,留意到event dispatcher,通过QAbstractEventDispatcher::instance()可以返回一个指针,这个看上去能处理系统级别的消息,而不是应用程序级别的消息。自己没尝试过,又尝试过的不妨介绍点经验

roywillow 2011-05-07 07:19
我的做法是,用QTimer定时取得鼠标的位置,然后判断是否移动

dbzhang800 2011-05-07 08:46
引用第4楼sbtree于2011-05-07 00:06发表的  :
这里我有个疑问,当屏幕保护在运行的时候,屏幕保护程序应该应该处在窗口系统的最顶层,通过notify函数触屏消息能被QApplication截获吗?
我在看QCoreApplication::winEventFilter函数的时候,留意到event dispatcher,通过QAbstractEventDispatcher::instance()可以返回一个指针,这个看上去能处理系统级别的消息,而不是应用程序级别的消息。自己没尝试过,又尝试过的不妨介绍点经验

恩,我还以为是他自己写屏保程序。如果不是,只能用系统底层的东西

gjf123 2011-05-09 10:52
roywillow大侠的解决方案很给力,唯一缺点就是效率低点,非常感谢roywillow等大侠的无私帮助

roywillow 2011-05-09 11:32
我曾经写过屏保,不过当时窗口是占满全屏的,并且窗口上无组件,只是重载paintEvent进行绘制

peterlin82 2011-05-10 12:00
小弟想使用dbzhang800大侠的方法覆盖QApplication:notify()自己写屏保程式。

但我程度太差,看了Qt Documentation后,还是不知覆盖QApplication:notify()该如何实做

有前辈能再帮忙覆盖QApplication:notify()的实例让小弟参考吗?

感激不尽 ^^

gjf123 2011-05-11 11:05
看过dbzhang800大侠的一些帖子,他的技术水平非常高,但非常的珍惜笔墨,稍点即止。同peterlin82 ,恳请dbzhang800等前辈能再帮忙覆盖QApplication:notify()的实例,感激不尽

cutemmll 2011-05-11 15:10
首先,如果要重新实现 QApplication:notify() ,是要建立在这个函数能被系统鼠标事件所触发,你首先要去确认在你的程序最小化时,系统鼠标事件能不能触发这个函数被调用。如果不能触发这个函数调用,你再怎么重新实现都是白搭。
个人认为,这个函数是不会被调用的,除非你用win32 的 hook 才能截获到系统的鼠标或者键盘事件。

弱弱地问一句,你的屏保是要运行在Windows下么??如果不是运行在Windows下,那前面的所有讨论都失去意义了。


gjf123 2011-05-11 17:11
嵌入式linux系统,程序窗口大小固定

cutemmll 2011-05-11 17:53
那就去重载 bool QApplication::qwsEventFilter ( QWSEvent * event ) 这个函数

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

  1. #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

application.cpp

  1. #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.cpp

  1. #include "application.h"
    #include "mainwindow.h"

    int main(int argc, char *argv[])
    {
        Application a(argc, argv);
        MainWindow w;
        w.show();

        return a.exec();
    }


上面两个函数你分别重载看下到底哪个有用,还是都没有用。我好久都没摸过arm板了。

peterlin82 2011-05-12 08:11
非常感谢cutemmll大侠的解说

小弟按照cutemmll大侠的做法,确实可抓到所有鼠标事件

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

再三感谢。

闲雨 2011-05-12 10:25
peterlin82  你说的这个可以吗?
bool Application::notify(QObject *obj, QEvent *e)
{
  if(e->type() == QEvent::MouseButtonPress)
  {
    //do something
  }
  return QApplication::notify(obj,e);
}

我自己也编译了一下,没有错误,但是运行的时候会报错的,系统无法运行

peterlin82 2011-05-12 10:32
引用第15楼闲雨于2011-05-12 10:25发表的  :
peterlin82  你说的这个可以吗?


可以,我这里并没出现任何问题

gjf123 2011-05-12 11:13
peterlin82,添个示例程序上来参考一下,感激中。。。

闲雨 2011-05-12 11:24
peterlin82
我试过了,是可以,原来是我理解错误了,确实好用,能检测到了
但是我还有疑问,我在//do something这里用qdebug可以看到信息了,但是我想建一个信号,发给我的主程序,主程序通过槽处理 函数,但是不成功,老是出错,不知道你是怎么弄的?
怎么给外面传的参数?

cutemmll 2011-05-12 12:30
如果用信号不行 就直接用函数调用吧。
再给小例子。
我只贴重要代码了。
头文件

  1. class Application : public QApplication
    {

    public:
        Application(int & argc, char ** argv);
        bool notify(QObject *, QEvent *);
        void setWindowInstance(MainWindow* wnd);

    private:
        MainWindow* window; //保存一个你窗体的指针

    };

cpp

  1. 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

  1. int main(int argc, char *argv[])
    {
        Application app(argc, argv);
        MainWindow w;
        w.show();
        app.setWindowInstance(&w);
        return app.exec();
    }

闲雨 2011-05-12 12:42
[quote]引用第19楼cutemmll于2011-05-12 12:30发表的 回 18楼(闲雨) 的帖子 :
如果用信号不行 就直接用函数调用吧。
再给小例子。
setWindowInstance
为什么我这里提示没有这个成员呢?

cutemmll 2011-05-12 12:44
这个函数是你继承了QApplication之后,然后你自己定义的。
汗~

gjf123 2011-05-12 13:27
感谢信
再次感谢cutemmll 大侠的详细帮助,小弟实验成功了。


goushi26 2017-05-16 16:20
cutemmll:如果用信号不行 就直接用函数调用吧。
再给小例子。
我只贴重要代码了。
头文件
....... (2011-05-12 12:30) 

我以前也是这么干的,后发发现软件运行的久了,有可能导致软件里面所有的信号槽失效,timer的超时信号也不响应,软件卡死。挺郁闷的。

夜风朗朗 2018-12-02 18:30
goushi26:我以前也是这么干的,后发发现软件运行的久了,有可能导致软件里面所有的信号槽失效,timer的超时信号也不响应,软件卡死。挺郁闷的。 (2017-05-16 16:20) 

对啊,我刚试过,可以,很开心,但是过了好一会大概1小时,信号和槽都失效了,是什么原因啊??

lite 2019-01-11 09:24
请问怎么解决的,我的也是一个小时后信号和槽都有问题了


查看完整版本: [-- qt  屏保 如何捕获全屏的鼠标事件[已经解决] --] [-- top --]



Powered by phpwind v8.7 Code ©2003-2011 phpwind
Gzip disabled