QObject

点击上方蓝字可直接关注!方便下次阅读。如果对你有帮助,可以点个在看,让它可以帮助到更多同志~

一、 QObject概述

 

说到Qt,你肯定首先想到的就是信号和槽,而这就不得不提到Qobject,这次和大家分享下QObject的相关内容,并对一些内容进行代码说明,方便理解。

 

QObject类是Qt对象模型,Qt绝大部分类都是继承该类实现的。 该模型的核心特点是提供了一种对象之间的通讯机制——信号和槽。你可以使用connect()将信号连接到插槽,也可以使用disconnect()来断开连接。为了避免一直通知槽函数,还可以使用blockSignals()来暂时阻塞信号。

 

QObjects会把组织一个对象模型,这也是我们常说的Qt对象树模型。当你创建一个QObject并使用其他对象作为父对象时,这个对象会自动添加到父对象的children()列表中。父对象拥有子对象的所有权,即父对象将在析构函数中自动删除其child对象。可以通过findChild()或findChildren()来查找对象。听起来有点绕,之后会使用代码进行说明【会有代码说明】。

 

每个对象都有一个对象名称(objectName())和类名称(class name), 他们都可以通过相应的 metaObject 对象来获得。你还可以通过 inherits() 方法来判断一个对象的类是不是从另一个类继承而来。

当对象被删除时,它发出destroyed()信号。你可以捕获这个信号来避免对QObject的无效引用【会有代码说明】。

 

QObject可以通过event()接收事件【会有代码说明】并且过滤其它对象的事件。详细情况请参考installEventFilter()和eventFilter()。

 

最后要注意的一点是,QObject在Qt中提供了基本的计时器支持。 有关定时器的高级支持,请参见QTimer 。

 

注意,对于实现信号和插槽或属性【本次不做说明】的任何对象,Q_OBJECT宏是必须的。  Qt官方强烈建议在QObject的所有子类中都使用该宏,不论它们是否实际使用信号和插槽或属性,因为不这样做可能会导致某些奇葩的错误。我个人是不愿意解决奇葩的错误的,比较浪费精力。

 

所有Qt的窗体都继承自QObject。 便捷函数isWidgetTye()返回对象是否是窗体部件的bool值。一些QObject函数(例如children())返回QObjectList。QObjectList是QList<QObject*>的typedef。【会有代码说明】

 

二、 对应代码

Widget类简要概述,继承自QWidget,没有.ui文件。

构造函数中:

①按钮实例化

QPushButton *button1 = new QPushButton(this);
button1->setText("one");


QPushButton *button2 = new QPushButton(this);
button2->setText("two");


QPushButton *button3 = new QPushButton(this);
button3->setText("three");


QPushButton *button4 = new QPushButton(this);
button4->setText("four");


button5 = new QPushButton(this);  //类成员变量
button5->setText("five");

②添加布局

QHBoxLayout *layout = new QHBoxLayout(this);   //
layout->addWidget(button1);
layout->addWidget(button2);
layout->addWidget(button3);
layout->addWidget(button4);
layout->addWidget(button5);


this->setLayout(layout);
this->resize(700, 200);   
//不将窗体设置大一些的话会有警告,警告如下
//(QPushButton(0x1f61ca50), QPushButton(0x1f61ce90),
// QPushButton(0x1f61cf10), QPushButton(0x1f61cf90),
// QPushButton(0x1f61cb10), QHBoxLayout(0x793f40))

上面程序警告是因为父对象几何框架较小不能容纳下子类视图,所以导致了对父对象的重新构造。重新设置父对象窗体大小即可;本程序中是因为按钮有最小尺寸导致的。

③使用概述QObject中的几个函数

bool ret = this->isWidgetType();
qDebug() << "isWidgetType" << ret;


qDebug() << this->children();


connect(button1,&QPushButton::clicked,
this,&Widget::slot_buttonClicked);  //qt5 new signal and slot


connect(button5,&QPushButton::destroyed,
this,&Widget::slot_objectDestroy);  //对象被删除会触发对应的槽函数

④槽函数

//第一个按钮按下触发删除按钮5的槽函数
void Widget::slot_buttonClicked()
{
    qDebug() << "You want to delete button5 !!!";


    if(nullptr != button5)
    {
        button5->deleteLater();
        button5 = nullptr;
    }


}


//对象被删除会触发对应的槽函数
void Widget::slot_objectDestroy()
{
    qDebug() << "Object destroy";
}

⑤事件处理例子

//事件处理
bool Widget::event(QEvent *e)
{
    if(QEvent::KeyPress == e->type())
    {
        QKeyEvent *keyEvent = static_cast<QKeyEvent *>(e);
        if (keyEvent->key() == Qt::Key_Shift)
        {
            qDebug() << "You press shift.";
            return true;
        }
    }


    // convey parent process
    return QWidget::event(e);


}

程序运行效果:

①运行效果

②点击第一个按钮效果 >> 按下Shift 按键效果:

这次不小结了~~~

QObject定时器的使用方法、原理及示例如下: - **使用方法**:QObject定时器主要通过实例化重写`timerEvent`时间事件来使用。通常无需进行`connect`操作(除非自定义信号),它一般作为基类,用于管理对象生命周期。可通过`startTimer`方法启动定时器,通过`killTimer`方法停止定时器 [^1][^2][^3]。 - **原理**:当定时器触发时,应用程序会发送一个`QTimerEvent`。在事件循环中,处理器按照事件队列的顺序来处理定时器事件。不过,当处理器正忙于其它事件处理时,定时器事件就不能立即处理 [^1]。 - **示例**:以下是一个使用QObject定时器的Python示例代码: ```python from PyQt5.Qt import * import sys class MyLabel(QLabel): def __init__(self, *args, **kwargs): # 封装一个控件 super().__init__(*args, **kwargs) self.setText("10") self.move(200, 200) self.setStyleSheet("font-size:22px;") def setSec(self, sec): self.setText(str(sec)) def startMyTimer(self, ms): self.timer_id = self.startTimer(ms) def timerEvent(self, *args, **kwargs): # 获取当前标签的内容 current_sec = int(self.text()) current_sec -= 1 self.setText(str(current_sec)) if current_sec == 0: print("stop!") self.killTimer(self.timer_id) app = QApplication(sys.argv) window = QWidget() # 创建一个窗口 window.setWindowTitle("QObject定时器的使用") # 窗口标题 window.resize(500, 500) # 设置窗口大小 window.move(400, 200) # 将窗口移动到电脑显示屏的一个位置 label = MyLabel(window) label.setSec(5) label.startMyTimer(500) window.show() # 展示窗口 sys.exit(app.exec_()) # app.exec_()为执行整个应用程序,为了告诉我们程序的退出,我们需要用sys.exit() ``` 该示例代码创建了一个`MyLabel`类,继承自`QLabel`,在`MyLabel`类中重写了`timerEvent`方法,在`timerEvent`方法中实现了倒计时的逻辑。在主程序中,创建了一个`MyLabel`对象,并启动了定时器,定时器每隔500毫秒触发一次`timerEvent`方法 [^3]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值