小悠.. 2023-12-06 18:43 采纳率: 0%
浏览 7

关于#qt#的问题:哪个标题栏应该会覆盖掉的,但是使用Qt 布完局运行,原生的标题栏、边框会闪烁出来

继承 QAbstractNativeEventFilter 重写nativeEventFilter这个方法,然后注册QCoreApplication::instance()->installNativeEventFilter(&native);然后直接布局,哪个标题栏应该会覆盖掉的,但是使用Qt 布完局运行,原生的标题栏、边框会闪烁出来。

img

  • 写回答

2条回答 默认 最新

  • CSDN-Ada助手 CSDN-AI 官方账号 2023-12-06 20:05
    关注

    【相关推荐】



    • 这篇博客: Qt事件过滤器原理(installEventFilter函数)中的 Qt事件过滤器原理(installEventFilter函数) 部分也许能够解决你的问题, 你可以仔细阅读以下内容或跳转源博客中阅读:

      本文为原创文章,转载请注明出处,或注明转载自“黄邦勇帅(原名:黄勇)

      本文出自本人原创著作《Qt5.10 GUI完全参考手册》网盘地址:
      https://pan.baidu.com/s/1iqagt4SEC8PUYx6t3ku39Q
      《C++语法详解》网盘地址:https://pan.baidu.com/s/1dIxLMN5b91zpJN2sZv1MNg

      若对C++语法不熟悉,建议参阅本人所著《C++语法详解》一书,电子工业出版社出版,该书语法示例短小精悍,对查阅C++知识点相当方便,并对语法原理进行了透彻、深入详细的讲解,可确保读者彻底弄懂C++的原理,彻底解惑C++,使其知其然更知其所以然。此书是一本全面了解C++不可多得的案头必备图书。

      事件过滤器用于拦截传递到目标对象的事件,这样可以实现监视目标对象事件的作用。
      1、Qt实现事件过滤器的步骤如下:
      ①、Qt调用
      void QObject::installEventFilter (QObject* filterObj)
      把filterObj对象安装(或注册)为事件过滤器,filterObj也称为过滤器对象。事件过滤器通常在构造函数中进行注册。
      ②、在上一步注册的filterObj对象,通过调用
      bool QObject::eventFilter(QObject* obj, QEvent* e);
      来接收拦截到的事件。也就是说拦截到的事件在filterObj对象中的eventFilter函数中处理。eventFilter的第一个参数obj指向的是事件本应传递到的目标对象。
      ③、使用QObject::removeEventFilter(QObject *obj)函数可以删除事件过滤器。
      2、事件过滤器处理事件的规则
      ①、过滤器对象的eventFilter()函数可以接受或拒绝拦截到的事件,若该函数返回false,则表示事件需要作进一步处理,此时事件会被发送到目标对象本身进行处理(注意:这里并未向父对象进行传递),若evetnFilter()返回true,则表示停止处理该事件,此时目标对象和后面安装的事件过滤器就无法获得该事件。
      ②、若同一对象安装了多个事件过滤器,则最后安装的过滤器首先被激活。
      3、为什么使用事件过滤器
      使用事件过滤器可以简化程序代码。比如按钮1和标签1,对按下A键的事件响应相同的操作,若不使用事件过滤器,则需要分别子类化按钮和标签部件,并重新实现各自的事件处理函数。再如使用同一个子类化按钮的类C创建的按钮1和按钮2,对按下键A,按钮1和按钮2需要作不同的响应,若不使用事件过滤器,则他们的响应是相同的,若使用事件过滤器,则可以拦截按钮1或按钮2的事件并作特殊处理。
      4、理解事件过滤器
      观察者模式:其原理为,设有一目标对象S,它有多个观察该对象的对象G1,G2,G3,当S发生变化时,S的观察者会依情形改变自身。应用于Qt事件过滤器,则是,首先使用S的成员函数installEventFilter函数把G1,G2,G3设置为S的观察者,所有本应传递给S的事件E,则先传递给观察者G1,G2,G3,然后观察者调用其成员函数eventFilter对传递进来的事件进行处理,若eventFilter返回true表示事件处理完毕,返回false则返回给被观察者S进行处理。见图2-13。
      在这里插入图片描述

      示例2.22:事件过滤器的使用

      #include <QApplication>
      #include<QWidget>
      #include<QMouseEvent>
      #include<QPushButton>
      #include<QObject>
      #include <iostream>
      using namespace std;
      class A:public QObject{public:  //该类的对象用作过滤器对象,使用事件过滤器需继承QObject
      bool eventFilter(QObject *w, QEvent *e){ 
      if(e->type()==QEvent::MouseButtonPress)
                  	{cout<<w->objectName().toStdString(); //验证w为事件本应到达的目标对象
                      cout<<"=Ak"<<endl;
                 		 return 1;  //返回1表示该事件不再进一步处理
                  	}
                      return 0;}  };  /*返回0表示其余事件交还给目标对象处理,本例应返回0,否则添加了该过滤器的安钮会无法显示。*/
      class B:public A{public:   //继承自类A
      bool eventFilter(QObject *w, QEvent *e){
      if(e->type()==QEvent::MouseButtonPress){
      cout<<w->objectName().toStdString()<<"=Bk"<<endl;
      return 0;}
      return 0;}	};
      class C:public QWidget{public: void mousePressEvent(QMouseEvent *e){cout<<"Ck"<<endl;}};
      class D:public QPushButton{public:void mousePressEvent(QMouseEvent *e){cout<<"DK"<<endl;}};
      
      int main(int argc, char *argv[]){
      QApplication a(argc,argv); 
      //创建对象,注意:本例父对象应先创建,以避免生命期过早结束
          A ma;   	B mb;   	 C mc;   	 D *pd=new D;   	 D *pd1=new D;
          pd->setText("AAA");    pd->move(22,22);      pd1->setText("BBB");    pd1->move(99,22);
          //设置对象名
          ma.setObjectName("ma");   	mb.setObjectName("mb");   	mc.setObjectName("mc");
          pd->setObjectName("pd");   	pd1->setObjectName("pd1");
          //设置父对象
          pd->setParent(&mc);    pd1->setParent(&mc);
          mb.setParent(&ma);    //①
           //注册过滤器对象
          pd->installEventFilter(&mb);  //②
          pd1->installEventFilter(&ma); //③
      
      mc.resize(333,222);    mc.show();    a.exec();    
      return 0;     }
      

      程序运行结果及说明(见图2-14)
      在这里插入图片描述
      当用鼠标按下按钮AAA时,输出pd=Bk和Dk。因为按钮AAA安装的过滤器对象为mb,因此由mb的eventFilter函数处理该事件,输出pd=BK,此时mb::eventFilter()返回0,表示此事件需作进一步处理,于是把该事件传递给目标对象处理(即pd所指向的对象),注意:本例虽然为mb设置了父对象ma,但事件并不会传递给父对象处理,而是返回给目标对象。此时调用D::mousePressEvent函数,输出Dk,至此事件处理结束。用鼠标按下按钮BBB输出pd1=Ak的原理略(较简单)
      示例2.23:添加多个事件过滤器

      #include <QApplication>
      #include<QWidget>
      #include<QMouseEvent>
      #include<QPushButton>
      #include<QObject>
      #include <iostream>
      using namespace std;
      class A:public QObject{public:
              bool eventFilter(QObject *w, QEvent *e){
                  if(e->type()==QEvent::MouseButtonPress)
                		{  cout<<"A"<<endl;
                  			return 0;  }//此处应返回0,注意,返回1事件将停止传递。
                   return 0;}		};
      class B:public QObject{public:
              bool eventFilter(QObject *w, QEvent *e){
                  if(e->type()==QEvent::MouseButtonPress){    cout<<"B"<<endl;return 0;  }
                  return 0;} 		};
      class C:public QObject{public:
              bool eventFilter(QObject *w, QEvent *e){
                  static int i=0;
                  if(e->type()==QEvent::MouseButtonPress){  cout<<"C="<<i++<<endl;return 0; }
                  return 0;} 		};
      int main(int argc, char *argv[]){ QApplication a(argc,argv); //Qt中QApplication类型的对象只能有一个
          //创建对象
          A ma;   B mb;    C mc,mc1;    //事件过滤器对象
          QWidget w;    QPushButton *pb=new QPushButton();   pb->setText("AAA");	pb->move(22,22); 
          pb->setParent(&w);//设置父对象
           //注册过滤器对象
          pb->installEventFilter(&ma);     	pb->installEventFilter(&mb); 
          pb->installEventFilter(&mc);		pb->installEventFilter(&mc1);
          w.resize(333,222);    w.show();    a.exec();       return 0;     }
      

      程序运行结果及说明(见图2-15)
      在这里插入图片描述
      按钮AAA安装的过滤器对象依次为ma,mb,mc,mc1,
      因此按下鼠标时,依次调用对象mc1,mc,mb,ma(即逆序)
      的eventFilter函数,需要注意的是:当安装了多个事件过滤
      器之后,eventFilter函数返回0并不会使事件返回给目标对
      象,而是传递给下一个过滤器对象,当所有过滤器对象都不处理该事件时才会传递给目标对象。
      2.6.6 自定义事件与事件的发送(若有需要请留言,然后视情况发表)

      本文作者:黄邦勇帅(原名:黄勇)

      在这里插入图片描述


    如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^
    评论

报告相同问题?

问题事件

  • 创建了问题 12月6日

悬赏问题

  • ¥15 为啥画版图在Run DRC会出现Connect Error?可我Calibre的hostname和计算机的hostname已经设置成一样的了。
  • ¥20 网站后台使用极速模式非常的卡
  • ¥20 Keil uVision5创建project没反应
  • ¥15 mmseqs内存报错
  • ¥15 vika文档如何与obsidian同步
  • ¥15 华为手机相册里面的照片能够替换成自己想要的照片吗?
  • ¥15 陆空双模式无人机飞控设置
  • ¥15 sentaurus lithography
  • ¥100 求抖音ck号 或者提ck教程
  • ¥15 关于#linux#的问题:子进程1等待子进程A、B退出后退出(语言-c语言)