• 31716阅读
  • 25回复

[提问]qt  屏保 如何捕获全屏的鼠标事件[已经解决] [复制链接]

上一主题 下一主题
离线gjf123
 

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

多谢各位大侠相助,小弟感激不尽
[ 此帖被gjf123在2011-05-12 14:17重新编辑 ]
离线dbzhang800

只看该作者 1楼 发表于: 2011-05-06
可以覆盖 QApplication:notify()
可以给 QApplication 安装事件过滤器
....
离线duduqq

只看该作者 2楼 发表于: 2011-05-06
估计和系统的API有关吧,
或者你在鼠标的驱动里试试能不能获得这个事件了
离线gjf123

只看该作者 3楼 发表于: 2011-05-06
dbzhang800  提供QApplication:notify()这个思路,觉得肯定可行,但对我这个初学者,较难,渴望dbzhang800  写点代码出来,非常感激。duduqq 大侠的指点,我明白,驱动里肯定能捕获的,感激,不过应用层能做的,就不要麻烦驱动了。
继续请求高手详细指点!小弟感激中
[ 此帖被gjf123在2011-05-06 18:15重新编辑 ]
离线sbtree
只看该作者 4楼 发表于: 2011-05-07
引用第1楼dbzhang800于2011-05-06 17:15发表的  :
可以覆盖 QApplication:notify()
可以给 QApplication 安装事件过滤器
....

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

只看该作者 5楼 发表于: 2011-05-07
我的做法是,用QTimer定时取得鼠标的位置,然后判断是否移动
专业维修核潜艇,回收二手航母、二手航天飞机,大修核反应堆,拆洗导弹发动机更换机油,无人侦察机手动挡改自动,航天飞机保养换三滤,飞碟外太空年检 ,各型号导弹加装迎宾踏板,高空作业擦洗卫星表面除尘、打蜡及抛光,东风全系列巡航导弹。并提供原子对撞机。量大从优,有正规发票。
离线dbzhang800

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

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

只看该作者 7楼 发表于: 2011-05-09
roywillow大侠的解决方案很给力,唯一缺点就是效率低点,非常感谢roywillow等大侠的无私帮助
[ 此帖被gjf123在2011-05-09 10:52重新编辑 ]
离线roywillow

只看该作者 8楼 发表于: 2011-05-09
我曾经写过屏保,不过当时窗口是占满全屏的,并且窗口上无组件,只是重载paintEvent进行绘制
专业维修核潜艇,回收二手航母、二手航天飞机,大修核反应堆,拆洗导弹发动机更换机油,无人侦察机手动挡改自动,航天飞机保养换三滤,飞碟外太空年检 ,各型号导弹加装迎宾踏板,高空作业擦洗卫星表面除尘、打蜡及抛光,东风全系列巡航导弹。并提供原子对撞机。量大从优,有正规发票。
离线peterlin82

只看该作者 9楼 发表于: 2011-05-10
小弟想使用dbzhang800大侠的方法覆盖QApplication:notify()自己写屏保程式。

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

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

感激不尽 ^^
[ 此帖被peterlin82在2011-05-10 12:00重新编辑 ]
离线gjf123

只看该作者 10楼 发表于: 2011-05-11
看过dbzhang800大侠的一些帖子,他的技术水平非常高,但非常的珍惜笔墨,稍点即止。同peterlin82 ,恳请dbzhang800等前辈能再帮忙覆盖QApplication:notify()的实例,感激不尽
[ 此帖被gjf123在2011-05-11 11:12重新编辑 ]
离线cutemmll
只看该作者 11楼 发表于: 2011-05-11
首先,如果要重新实现 QApplication:notify() ,是要建立在这个函数能被系统鼠标事件所触发,你首先要去确认在你的程序最小化时,系统鼠标事件能不能触发这个函数被调用。如果不能触发这个函数调用,你再怎么重新实现都是白搭。
个人认为,这个函数是不会被调用的,除非你用win32 的 hook 才能截获到系统的鼠标或者键盘事件。

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

c------------enjoy qt & enjoy life-----------++
离线gjf123

只看该作者 12楼 发表于: 2011-05-11
嵌入式linux系统,程序窗口大小固定
[ 此帖被gjf123在2011-05-11 17:11重新编辑 ]
离线cutemmll
只看该作者 13楼 发表于: 2011-05-11
那就去重载 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. }


上面两个函数你分别重载看下到底哪个有用,还是都没有用。我好久都没摸过arm板了。
[ 此帖被cutemmll在2011-05-11 17:57重新编辑 ]
c------------enjoy qt & enjoy life-----------++
离线peterlin82

只看该作者 14楼 发表于: 2011-05-12
非常感谢cutemmll大侠的解说

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

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

再三感谢。
[ 此帖被peterlin82在2011-05-12 08:13重新编辑 ]
离线闲雨

只看该作者 15楼 发表于: 2011-05-12
peterlin82  你说的这个可以吗?
bool Application::notify(QObject *obj, QEvent *e)
{
  if(e->type() == QEvent::MouseButtonPress)
  {
    //do something
  }
  return QApplication::notify(obj,e);
}

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

只看该作者 16楼 发表于: 2011-05-12
引用第15楼闲雨于2011-05-12 10:25发表的  :
peterlin82  你说的这个可以吗?


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

只看该作者 17楼 发表于: 2011-05-12
peterlin82,添个示例程序上来参考一下,感激中。。。
[ 此帖被gjf123在2011-05-12 11:13重新编辑 ]
离线闲雨

只看该作者 18楼 发表于: 2011-05-12
peterlin82
我试过了,是可以,原来是我理解错误了,确实好用,能检测到了
但是我还有疑问,我在//do something这里用qdebug可以看到信息了,但是我想建一个信号,发给我的主程序,主程序通过槽处理 函数,但是不成功,老是出错,不知道你是怎么弄的?
怎么给外面传的参数?
[ 此帖被闲雨在2011-05-12 12:21重新编辑 ]
离线cutemmll
只看该作者 19楼 发表于: 2011-05-12
回 18楼(闲雨) 的帖子
如果用信号不行 就直接用函数调用吧。
再给小例子。
我只贴重要代码了。
头文件
  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. };

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

main.cpp
  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. }
c------------enjoy qt & enjoy life-----------++
离线闲雨

只看该作者 20楼 发表于: 2011-05-12
Re:回 18楼(闲雨) 的帖子
[quote]引用第19楼cutemmll于2011-05-12 12:30发表的 回 18楼(闲雨) 的帖子 :
如果用信号不行 就直接用函数调用吧。
再给小例子。
setWindowInstance
为什么我这里提示没有这个成员呢?
离线cutemmll
只看该作者 21楼 发表于: 2011-05-12
回 20楼(闲雨) 的帖子
这个函数是你继承了QApplication之后,然后你自己定义的。
汗~
c------------enjoy qt & enjoy life-----------++
离线gjf123

只看该作者 22楼 发表于: 2011-05-12
感谢信
再次感谢cutemmll 大侠的详细帮助,小弟实验成功了。

[ 此帖被gjf123在2011-05-12 13:28重新编辑 ]
离线goushi26

只看该作者 23楼 发表于: 2017-05-16
回 cutemmll 的帖子
cutemmll:如果用信号不行 就直接用函数调用吧。
再给小例子。
我只贴重要代码了。
头文件
....... (2011-05-12 12:30) 

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

只看该作者 24楼 发表于: 2018-12-02
回 goushi26 的帖子
goushi26:我以前也是这么干的,后发发现软件运行的久了,有可能导致软件里面所有的信号槽失效,timer的超时信号也不响应,软件卡死。挺郁闷的。 (2017-05-16 16:20) 

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

只看该作者 25楼 发表于: 2019-01-11
请问怎么解决的,我的也是一个小时后信号和槽都有问题了
快速回复
限100 字节
 
上一个 下一个