​​​​通过给定一个全屏的位置得到该位置处是哪一个控件、 遍历窗口中的每一个元素

通过给定一个全屏的位置得到该位置处是哪一个控件(以下方法)

[static] QWidget *QApplication::widgetAt(const QPoint &point)

场景:通过位置获取该位置处的widget后,然后进行判断,是不是某个或某些控件,从而做一些处理

举例:

鼠标按下时,获取鼠标的位置,通过这个位置来判断鼠标在哪个控件按下,然后弹出对应提示

#include <QWidget>
#include<QLabel>
#include<QMouseEvent>
#include<QApplication>
#include<QMessageBox>

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr): QWidget(parent)
    {
        resize(500,500);
        label_1=new QLabel(this);
        label_1->setText("我是label_1");
        label_1->setAlignment(Qt::AlignCenter);
        label_1->setFixedSize(200,100);
        label_1->setStyleSheet(R"(QLabel{background-color:pink;border:1px solid black})");

        label_2=new QLabel(this);
        label_2->setText("我是label_2");
        label_2->setAlignment(Qt::AlignCenter);
        label_2->setFixedSize(200,100);
        label_2->move(0,110);
        label_2->setStyleSheet(R"(QLabel{background-color:pink;border:1px solid black})");

    }
    ~Widget()=default;
protected:
    //重写鼠标按下事件
    //鼠标按下的位置若是标签,则弹出对应提示
    void mousePressEvent(QMouseEvent* ev)
    {
        //通过这个静态方法可根据位置获取位置处的Widget的地址
        auto pressed_widgt=QApplication::widgetAt(ev->globalPos());
        if(pressed_widgt==label_1)
        {
            //按下处是label_1
            QMessageBox::information(this,"","hello,I am label_111!");
        }
        if(pressed_widgt==label_2)
        {
            //按下处是label_2
            QMessageBox::information(this,"","hello,I am label_222!");
        }
        if(pressed_widgt==this)
        {
            //按下处是主窗口
            QMessageBox::information(this,"","hello,I am main window!");
        }

    }
private:
    QLabel* label_1;
    QLabel* label_2;

};

 遍历窗口中的每一个元素

使用场景:比如某个窗口里面多层嵌套很多个控件,给每一个控件设置鼠标追踪。

举例:

窗口刚刚创建重绘时,给窗口里面每一个元素都设置鼠标追踪,并打印出被设置了的子元素的类名

 

#include <QWidget>
#include<QPushButton>
#include<QHBoxLayout>
#include<QVBoxLayout>
#include<QEvent>
#include<mutex>

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr): QWidget(parent)
    {
        //整个窗口采用垂直布局
        QVBoxLayout* v_box=new QVBoxLayout(this);
        btn1=new QPushButton(this);
        btn1->setFixedSize(100,50);
        btn1->setText("按钮1");
        v_box->addWidget(btn1);

        btn2=new QPushButton(this);
        btn2->setFixedSize(100,50);
        btn2->setText("按钮2");
        v_box->addWidget(btn2);

        btn3=new QPushButton(this);
        btn3->setText("按钮3");

        btn4=new QPushButton(this);
        btn4->setText("按钮4");

        //按钮3和按钮4在一个子widget中
        QWidget*sub_widget= new QWidget(this);
        QHBoxLayout* h_box=new QHBoxLayout(sub_widget);
        h_box->addWidget(btn3);
        h_box->addWidget(btn4);
        //这个子widget也添加进整个窗口的垂直布局中
        v_box->addWidget(sub_widget);

        //给窗口安装事件过滤器
        this->installEventFilter(this);
    }
    ~Widget()=default;

    //给窗口每一个元素设置鼠标追踪
    void setAllWidgetMouseTracing(QWidget* widget)
    {
        widget->setMouseTracking(true);
        //获取这个widget里面的子元素
        QList<QObject*> list=widget->children();
        for(const auto& object:list)
        {
            //打印下每个元素
            //获取每个元素的类名
            qDebug()<<object->metaObject()->className();
            //如果这个子元素是QWidget,那么他下面可能还有子元素
            if(object->metaObject()->className()==QStringLiteral("QWidget"))
            {
                //给这个子元素设置鼠标追踪
                QWidget* w=(QWidget*)object;
                w->setMouseTracking(true);
                //子元素里若还有子元素,则递归下去继续设置
                setAllWidgetMouseTracing(w);
            }
        }

    }

    //在窗口最开始重绘时设置一次就够了
    //在事件过滤器中捕获窗口的重绘事件
    bool eventFilter(QObject* watched,QEvent* ev)
    {
        if(ev->type()==QEvent::Paint)
        {
            static std::once_flag just_once;
            std::call_once(just_once,&Widget::setAllWidgetMouseTracing,this,this);
        }

        return QWidget::eventFilter(watched,ev);
    }

private:
    QPushButton* btn1;
    QPushButton* btn2;
    QPushButton* btn3;
    QPushButton* btn4;
};

学习链接:https://github.com/0voice 

  • 9
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值