通过给定一个全屏的位置得到该位置处是哪一个控件(以下方法)
[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