Qt技巧:从实例浅谈提升到类、eventFilter的作用

2022/06/02 技巧 共 2518 字,约 8 分钟

从实例浅谈提升到类、eventFilter的作用

本文从的开发的会议软件LBD_VideoMeeting_Meeting.exe出发,浅谈一下两个在开发中很省事的方案:提升到类 和 eventFilter的开发实例

问题一:

我们在实际开发的时候经常会用到一些重复且特定的组件组合,比如

image

可以看到,这样一个软件,它由很多的窗体组成,每一个窗体又要拆分成很多小的控件来看

image

比如这个窗口,就有两个小控件,一个是用户的头像控件,一个是用户的姓名label,看起来很简单对吧,只要每次移动摄像头画面的时候,让头像控件和label控件跟着移动就可以了。

说的轻巧,但是如果是八个,十个,一百个摄像头呢?或者说一个摄像头画面里的有七八个控件要跟着一起移动呢?你还是这么移动吗?工作量可想而知。

那我们有没有简单一点的方法,能不能把这几个控件组合一下,看成是一个新的,属于我自己的控件呢?

问题二:

我们在实际开发的时候会遇到这样的问题:我们有时候想点击一个非按钮的物体,比如widget,想让它也能反馈出信号,但是widget并不像QPushButton那样,可以有一个默认的槽函数on_pushButton_click

这时候就犯难了,那点击事件该怎么写呢?

更进一步的,除了点击事件,还有鼠标悬停事件,比如hoverEnter,hoverLeave,并不是所有的控件都有默认的槽函数,但是实际开发需求又可能千奇百怪,总有可能我们需要用到这样那样的自定义事件

那我们该如何是好呢?

问题一答案:提升到类

我们可以通过提升到类的方式,将几个控件组合为一体,像一个单独的控件一样,给它赋予一些方法让它单独成为一个你可以复写的类,控制类中控件的交互。

我们举个例子,就拿我上述这个问题举例:我想在一个Widget里面摆上一个头像,又想摆上一个姓名标签,该怎么做?

让我们来提供一个方法:提升到类。

1.什么是提升到类?

其实提升到类,说起来也很简单:就相当于制作了一个新的公用控件,和pushButton和Widget一样,然后随意拖一个任意控件上去,提升到类就相当于是把那个你制作的公用控件赋给你拖上去的任意控件。

也就是说,我们有一个全新的ui文件,就像建立一个全新的窗口那样,只是调用的方式不一样。新的窗口我们用的是新建一个指针,而提升到类则只是把这个新的ui当成了一个控件来用,这么理解就好了。

2.如何提升到类?

1.首先我们要做一个新的ui文件。

image

假设这就是我们的新的UI文件,比如这个Camitem.ui,这个文件就是我们新的控件的依据。

2.生成ui文件之后,我们要把这个ui文件拖到我们的工程文件中去,编译,才可以获得ui_Camaitem.h文件

image

3.右键解决方案,添加,QtClass,添加一个Qt Widget Class

这样就有一个.h文件和一个.cpp文件了。

然后我们在头文件.h文件里面加上include “ui_xx.h文件,这样就可以编写这个自定义控件内的方法了,比如我们想要一个外部方法,给一个外部调用的接口,可以修改这个name的text

image

比如这里,SetPic方法就是修改头像图片的方法,SetName就是修改名称的方法。

我们的构造函数和其他的widget类的构造函数写法一样,比如:

image

操作控件的方法:

image

3.正式提升到类

ok这样我们就可以拿一些控件来给它提升到类了,比如我们在正式开发的时候,要用这些控件了,怎么办?下面这张图黑色的窗体本身是Widget,我们将他们提升到类Camitem

image

image

在这里填上类名称和包含其类的头文件,也就是我们前面写的那个文件和那个类就可以了。

点个添加,再提升就可以了,就这么简单,这样就相当于是这个控件被我们写的这个控件UI灌注了。

然后我们这个在我们主类中的ui指向的窗体控件指针,就会指向这个类了。

4. 使用这个类

比如我们这个 Cam_Stu1 我们把它提升到Camitem类上去

那我们怎么调用这个类的方法呢?就像调用普通的控件方法一样调用自己写的方法就好了

ui.Cam_Stu1->SetPic(strMessage);

ui.Cam_Stu1->SetName(strMessage);

就这样写就可以了。

问题二答案:检测事件

其实这个问题特别简单。

首先我们要找到我们需要监听的那个控件,就要给这个控件注册上eventFilter,比如我们要监听label,那么给它注册上监听器

ui.label->installeventFilter(this);

然后我们写上eventFilter方法如下:

bool eventFilter(QObject *obj, QEvent *event);

然后这个类会自动监听,其中obj为我们监听的对象,event为触发的事件

举个实例吧,这个不难。

bool LBD_VideoMeeting_Meeting::eventFilter(QObject * obj, QEvent * event)
{	if (obj == (QObject*)ui.centralWidget) {
    if (event->type() == QEvent::Enter) {
      ui.mengban->show();
      ui.mengban->raise();
      ui.wid_close->raise();
    }
    else if (event->type() == QEvent::Leave) {
      ui.mengban->hide();
      ui.wid_close->raise();
    }
  }else if (obj = (QObject*)ui.Cam_Invite) {
    if (event->type() == QMouseEvent::MouseButtonPress) {
      if (TypeUser == 1) { on_btn_invite_clicked(true); 
      }
    }
  }
  else if (obj == (QObject*)ui.wid_close) {
    if (event->type() == QMouseEvent::MouseButtonPress) {
      if (TypeUser == 1) {
        on_btn_invite_clicked(true);
      }
    }
  }

  return false;
}

文档信息

Search

    Table of Contents