当前位置: 首页 > wzjs >正文

太原网站制作小程序网站更新的意义

太原网站制作小程序,网站更新的意义,文件标签wordpress,350做网站深圳Qt 信号和槽 1. 信号与槽的概念 Qt信号与槽通信机制能够完成任意两个Qt对象之间的通信,其中,信号会在某个特定的情况或动作下被触发,槽等同于接收并处理信号的函数。使用信号与槽机制进行通信的对象必须是QObject的子类对象,且类…

Qt 信号和槽

1. 信号与槽的概念

  Qt信号与槽通信机制能够完成任意两个Qt对象之间的通信,其中,信号会在某个特定的情况或动作下被触发,槽等同于接收并处理信号的函数。使用信号与槽机制进行通信的对象必须是QObject的子类对象,且类的声明中必须使用 Q_OBJECT 宏。

2. 信号

signals:void SignalAgeChanged(int);

  signals为Qt关键字,不是C++关键字,它指出从此处进入信号声明区,信号函数中的参数,就是对象之间通信时交换的数据。
信号函数定义的注意点:
(1)返回值是void类型,因为触发信号函数的目的是执行与其绑定的槽函数,无须信号函数返回任何值;
(2)程序设计者只能声明而不能实现信号函数。信号函数的实现由Qt的MOC工具在程序编译时完成;
(3)信号函数被MOC工具自动设置为protected,因而只有包含一个信号函数的那个类以及其派生类才能使用该信号函数;
(4)信号函数的参数个数、类型由程序设计者自由设定,这些参数的职责是封装类的状态信息,并将信息传递给槽函数;
(5)只有QObject及其派生类才可以声明信号函数;

3. 槽


public slots:void SlotAgeChanged(int nAge);

  槽(Slot)就是对信号响应的函数。槽函数和普通C++成员函数一样,可以定义在类的任何区域(public、protected或private),可以具有任何参数,也可以被直接调用。
槽函数的特点:
(1)槽函数可以有参数,但是参数不能有默认值;
(2)槽函数的返回值为void,因为信号和槽的机制是单向的,即信号被发送后,与其绑定的槽函数会被执行,但不要求槽函数返回任何执行结果;
(3)只有QObject及其派生类才可以定义槽函数;
(4)槽函数的访问权限(public、protected或private)不影响QObject::connect()函数关联信号和槽,只要信号和槽绑定成功,即使槽函数的访问权限为private也会被执行;

4. 信号和槽的关联

  信号与槽的关联方式:

  • 一对一
  • 一对多
  • 多对一
  • 信号关联信号
// 采用函数名称的形式关联信号槽QMetaObject::Connection QObject::connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type = Qt::AutoConnection);// 如果信号和槽函数有参数,需要把形参也写上
connect(sender, SIGNAL(signal_function(QString)), receiver, SLOT(slot_function(QString)));// 采用函数指针的形式关联信号槽
QMetaObject::Connection QObject::connect(const QObject *sender, PointerToMemberFunction signal, const QObject *receiver, PointerToMemberFunction method, Qt::ConnectionType type = Qt::AutoConnection);
// 不用写函数的形参
connect(sender, &SenderClass::signal_function), receiver, &ReceiverClass::slot_function);

建议采用第二中函数指针的写法,因为当信号和槽的函数参数较多时,第一种方法要写很多形参代码,不仅代码多,还容易出错;

// .h
#ifndef STUDENT_H
#define STUDENT_H#include <QObject>class Student : public QObject
{Q_OBJECTpublic:explicit Student(QObject *parent = nullptr);~Student() = default;public:void SetAge(int nAge);int GetAge();public slots:// 没有定义成槽函数的形式,只是普通类成员函数void AgeChanged(int nAge);signals:void SignalAgeChanged(int);private:int m_nAge;
};#endif // STUDENT_H// .cpp
#include "Student.h"
#include <QDebug>Student::Student(QObject *parent) : QObject(parent), m_nAge(15)
{}void Student::SetAge(int nAge)
{m_nAge = nAge;emit SignalAgeChanged(nAge);
}int Student::GetAge()
{return m_nAge;
}void Student::AgeChanged(int nAge)
{qDebug() << "Age changed = " << nAge;
}#include <QCoreApplication>
#include "Student.h"// 测试
int main(int argc, char *argv[])
{QCoreApplication a(argc, argv);Student stu;QObject::connect(&stu, &Student::SignalAgeChanged, &stu, &Student::AgeChanged);stu.SetAge(10);return a.exec();
}

connect函数的第五个参数,默认采用Qt::AutoConnection的方式,此方式下Qt会根据信号员对象和接收对象所属的线程来处理;

常量含义
Qt::AutoConnection0(Default) If the receiver lives in the thread that emits the signal, Qt::DirectConnection is used. Otherwise, Qt::QueuedConnection is used. The connection type is determined when the signal is emitted.
Qt::DirectConnection1The slot is invoked immediately when the signal is emitted. The slot is executed in the signalling thread.
Qt::QueuedConnection2The slot is invoked when control returns to the event loop of the receiver’s thread. The slot is executed in the receiver’s thread.
Qt::BlockingQueuedConnection3Same as Qt::QueuedConnection, except that the signalling thread blocks until the slot returns. This connection must not be used if the receiver lives in the signalling thread, or else the application will deadlock.
Qt::UniqueConnection0x80This is a flag that can be combined with any one of the above connection types, using a bitwise OR. When Qt::UniqueConnection is set, QObject::connect() will fail if the connection already exists (i.e. if the same signal is already connected to the same slot for the same pair of objects). This flag was introduced in Qt 4.6.

5. 信号和槽传值的问题

  • 在同一个线程中
    当信号和槽都在同一个线程中时,值传递参数和引用传递参数有区别: 值传递会复制对象;引用传递不会复制对象;
    还是以之前的示例为程序,将信号与槽的值参数改为引用:
#ifndef STUDENT_H
#define STUDENT_H#include <QObject>class Student : public QObject
{Q_OBJECTpublic:explicit Student(QObject *parent = nullptr);~Student() = default;public:void SetAge(int nAge);int GetAge();public slots:// 没有定义成槽函数的形式,只是普通类成员函数void AgeChanged(int& nAge);						// 信号和槽都改成了引用signals:void SignalAgeChanged(int&);					// 信号和槽都改成了引用private:int m_nAge;
};#endif // STUDENT_H#include "Student.h"
#include <QDebug>Student::Student(QObject *parent) : QObject(parent), m_nAge(15)
{}void Student::SetAge(int nAge)
{m_nAge = nAge;emit SignalAgeChanged(m_nAge);
}int Student::GetAge()
{return m_nAge;
}void Student::AgeChanged(int& nAge)
{qDebug() << "Age changed = " << nAge;nAge = 20;              // 将数据改为 20
}int main(int argc, char *argv[])
{QCoreApplication a(argc, argv);Student stu;QObject::connect(&stu, &Student::SignalAgeChanged, &stu, &Student::AgeChanged);stu.SetAge(10);qDebug() << "Age = " << stu.GetAge();       // 打印出来的值为 20return a.exec();
}

在槽函数中,重新设置了值,最后结果变成了在槽函数中设置的值。

  • 不在同一个线程中
    当信号和槽不在同一个线程中时,分两种情况:
  1. connect时使用AutoConnection(跨线程默认是QueuedConnection):值传递参数和引用传递参数没有区别,都会复制对象;
  2. connect时使用DirectConnection,测试结果和在同一线程中的结果相同;
// Student类
#ifndef STUDENT_H
#define STUDENT_H#include <QObject>class Student : public QObject
{Q_OBJECTpublic:explicit Student(QObject *parent = nullptr);~Student() = default;public:void SetName(QString strName);QString GetName();signals:void SignalNameChanged(const QString&);private:QString m_strName;
};#include "Student.h"
#include <QDebug>Student::Student(QObject *parent) : QObject(parent)
{}
void Student::SetName(QString strName)
{m_strName = strName;emit SignalNameChanged(m_strName);
}QString Student::GetName()
{return m_strName;
}// Worker类
#endif // STUDENT_H#ifndef MYWORKER_H
#define MYWORKER_H#include <QObject>
#include <Windows.h>class MyWorker : public QObject
{Q_OBJECT
public:explicit MyWorker(HANDLE hEvent, QObject *parent = nullptr);public slots:void SlotNameChanged(const QString& strName);private:HANDLE m_hEvent;
};#endif // MYWORKER_H#include "MyWorker.h"MyWorker::MyWorker(HANDLE hEvent, QObject *parent) : QObject(parent), m_hEvent(hEvent)
{}void MyWorker::SlotNameChanged(const QString& strName)
{QString& strNameTemp = const_cast<QString&>(strName);strNameTemp = QString("Zhangsan");			// 设置为 ZhangsanSetEvent(m_hEvent);
}// 使用 DirectConnection
#include <QCoreApplication>
#include <Windows.h>
#include "Student.h"
#include <QDebug>
#include <QThread>
#include <memory>
#include "MyWorker.h"using std::unique_ptr;void Test()
{Student stu;HANDLE hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);unique_ptr<MyWorker> upWorker = std::make_unique<MyWorker>(hEvent);unique_ptr<QThread> upThread = std::make_unique<QThread>();upWorker->moveToThread(upThread.get());QObject::connect(&stu, &Student::SignalNameChanged, upWorker.get(), &MyWorker::SlotNameChanged, Qt::DirectConnection);upThread->start();ResetEvent(hEvent);stu.SetName(QString("Wangwu"));DWORD nRtn = WaitForSingleObject(hEvent, 5000);qDebug() << "Return = " << nRtn;qDebug() << "Name = " << stu.GetName();         // 输出 ZhangsanupThread->quit();upThread->wait();
}int main(int argc, char *argv[])
{QCoreApplication a(argc, argv);Test();return a.exec();
}// 使用 AutoConnection
#include <QCoreApplication>
#include <Windows.h>
#include "Student.h"
#include <QDebug>
#include <QThread>
#include <memory>
#include "MyWorker.h"using std::unique_ptr;void Test()
{Student stu;HANDLE hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);unique_ptr<MyWorker> upWorker = std::make_unique<MyWorker>(hEvent);unique_ptr<QThread> upThread = std::make_unique<QThread>();upWorker->moveToThread(upThread.get());QObject::connect(&stu, &Student::SignalNameChanged, upWorker.get(), &MyWorker::SlotNameChanged);upThread->start();ResetEvent(hEvent);stu.SetName(QString("Wangwu"));DWORD nRtn = WaitForSingleObject(hEvent, 5000);qDebug() << "Return = " << nRtn;qDebug() << "Name = " << stu.GetName();         // 输出 WangwuupThread->quit();upThread->wait();
}int main(int argc, char *argv[])
{QCoreApplication a(argc, argv);Test();return a.exec();
}

文章转载自:

http://00000000.wsjnr.cn
http://00000000.wsjnr.cn
http://00000000.wsjnr.cn
http://00000000.wsjnr.cn
http://00000000.wsjnr.cn
http://00000000.wsjnr.cn
http://00000000.wsjnr.cn
http://00000000.wsjnr.cn
http://00000000.wsjnr.cn
http://00000000.wsjnr.cn
http://00000000.wsjnr.cn
http://00000000.wsjnr.cn
http://00000000.wsjnr.cn
http://00000000.wsjnr.cn
http://00000000.wsjnr.cn
http://00000000.wsjnr.cn
http://00000000.wsjnr.cn
http://00000000.wsjnr.cn
http://00000000.wsjnr.cn
http://00000000.wsjnr.cn
http://00000000.wsjnr.cn
http://00000000.wsjnr.cn
http://00000000.wsjnr.cn
http://00000000.wsjnr.cn
http://00000000.wsjnr.cn
http://00000000.wsjnr.cn
http://00000000.wsjnr.cn
http://00000000.wsjnr.cn
http://00000000.wsjnr.cn
http://00000000.wsjnr.cn
http://www.dtcms.com/wzjs/602421.html

相关文章:

  • 网站建设证有静态网站开发基础
  • 国内企业网站模板网站关键词多少个字数 站长网
  • wordpress修改时区谷歌seo需要做什么的
  • 建设银行招聘网站企业推广方案范例
  • 江苏伟业建设集团网站大学生网站设计作业
  • 网站变灰色湖北智能网站建设推荐
  • 嘉兴seo公司网站济南网站制作平台
  • 设计素材网站合集网站建设百度推广总结
  • 网站平台怎么做企业招聘
  • 合肥网站建设设计公司室内设计专业公司排名
  • 网站开发公众号开发网页设计与制作教程杨选辉课后答案
  • 哪个网站是做红酒酒的企业网站建设包括哪些
  • logo在线设计网站wordpress上传类型
  • 海南手机网站建设公司哪家好万维网网站域名续费
  • dedecms 购物网站安徽工程建设信息网官网
  • 烟台微网站建设wordpress 图片环绕
  • 网站建设书籍湖南建设人力
  • 自学编程的网站米拓建站官网怎么用不了
  • 培训类网站建设东莞网站搜索排名
  • 做外贸平台还是网站汉语资源建设相关网站
  • 2019做什么类型网站成都市城乡建设管理局网站
  • 微网站开发项目合作协议wordpress视频链接
  • 网站怎样做自适应分辨率大小网页打不开但是微信和qq都可以上
  • 网站开发的税率是多少钱营销型网站建设有哪些平台
  • 网站seo新闻潜江网页设计
  • 超酷 flash 网站网站描述怎么写好
  • 网站做外链的具体步骤免费一键logo设计
  • 广告传媒建设网站标书制作软件
  • 哪家网站建设服务好啊中国新闻社是事业编制吗
  • 福田网站建设费用预算可不可以免费创建网站