网站建设好的公司,导航wordpress模板下载地址,龙岩网站设计 都找推商吧系统,学院管理网站建设1、概念 信号和槽是两种函数#xff0c;这是Qt在C基础上新增的特性#xff0c;类似于其他技术中的回调的概念。 信号和槽通过程序员提前设定的“约定”#xff0c;可以实现对象之间的通信#xff0c;有两个先决的条件#xff1a; 通信的对象必须都是从QObject类中派生出来…1、概念 信号和槽是两种函数这是Qt在C基础上新增的特性类似于其他技术中的回调的概念。 信号和槽通过程序员提前设定的“约定”可以实现对象之间的通信有两个先决的条件 通信的对象必须都是从QObject类中派生出来的。类中要有Q_OBJECT宏。 2、函数原型 信号槽需要在使用前进行“约定”这个约定被称为连接。 【例子】如果金龙考试考了100分新宇请金龙吃饭。 // 参数1const QObject * sender 发射者表示因发起对象
// 参数2const char * signal信号函数表示因的发起动作使用SIGNAL()包裹。
// 参数3const QObject * receiver 接收者表示果的发起对象
// 参数4const char * method 槽函数表示果发起的动作请吃饭SLOT()包裹。
QObject:: connect(const QObject * sender, const char * signal, const QObject * receiver, const char * method)[static]3、实现 为了学习把信号槽分为三种实现方式。 自带信号 - 自带槽自带信号 - 自定义槽自定义信号 3.1 自带信号-自带槽 这种连接方式是最简单的因为信号函数和槽函数都是Qt内置的只需要在文档中查询出函数后使用connect函数连接即可。 查找函数 F1F1 查找手册 查找函数在对应的QPushButton Class基类继承自QAbstractButton类查找自带槽Public Slots找到对应槽函数click // 按钮按下后时发射的信号
void QAbstractButton:: clicked(bool checked false)[signal]查询函数在对应的Widget基类查找自带槽Public Slots找到对应槽函数close // 关闭 槽函数
bool QWidget:: close()dialog.h #ifndef DIALOG_H
#define DIALOG_H#include QDialog
#include QDebug
#include QPushButtonclass Dialog : public QDialog
{Q_OBJECTpublic:Dialog(QWidget *parent 0);~Dialog();QPushButton *btn; // 成员变量
};#endif // DIALOG_H dialog.cpp #include dialog.h
Dialog::Dialog(QWidget *parent): QDialog(parent)
{//设置窗口的宽高resize(500,500);btn new QPushButton(关闭,this);// 设置按钮的位置btn-move(200,250);//but 发起者、SIGNAL()包裹发起动作点击、this 接收者、SLOT(close()) 接收结果 close关闭窗口connect(btn,SIGNAL(clicked()),this,SLOT(close()));
}
Dialog::~Dialog()
{// C内存回收delete btn;
}3.2 自带信号-自定义槽 Qt不可能内置所有执行的动作代码特别是一些复杂的操作需要开发者手动编写槽函数。这种方式也是所有连接方式中使用最多的。 槽函数时一个特殊的成员函数在声明的时候权限的作用主要是修饰其作为普通成员函数的使用效果不影响信号槽的连接效果。 【例子】点击按钮向右边和下面移动窗口10个像素。同时输出当前窗口的坐标。 dialog.h #ifndef DIALOG_H
#define DIALOG_H
// 添加头文件QDialog对话框基类Qt自带类型通常使用Q开头
#include QDialog
#include QDebug
#include QPushButton
// 自定义对话框类
// 继承于QDialog类
class Dialog : public QDialog
{// 是一个宏是必要条件一个标准有这个宏才可以用connect链接Q_OBJECT
public:Dialog(QWidget *parent 0); // 构造函数~Dialog(); // 析构函数QPushButton *btn; // 成员变量//声明自定义槽函数
private slots://最小权限法则能使用私有权限就是用私有固定写法表示声明的是一个槽函数connect连接时才能找到该槽函数void mySlot();//小驼峰命名第一个单词首字母小写其他大写
};
#endif // DIALOG_Hdialog.cpp #include dialog.h
// 构造函数定义
// parent 参数
Dialog::Dialog(QWidget *parent): QDialog(parent) // 透传构造
{//设置窗口宽高resize(500,500);btn new QPushButton(移动,this);//设置按钮位置btn-move(200,200);//but 发起者、SIGNAL(clicked()) 发起动作点击、this 接收者、SLOT(close()) 接收结果 close关闭窗口connect(btn,SIGNAL(clicked()),this,SLOT(mySlot()));
}
// 析构函数类外定义
Dialog::~Dialog()
{// C内存回收delete btn;
}
//槽函数定义
void Dialog::mySlot()
{//先获取当前窗口坐标int x this-x();//坐标函数返回值就是坐标值int y this-y();//移动坐标位置,每次获取的都是最新的坐标位置所以不需要赋值move(x10,y10);//输出当前坐标位置qDebug()x10y10;
} 3.3 自定义信号 emit关键字发射。 为了讲解强行使用自定义信号并非问题的最优解主要学习写法。 信号函数是一个非常特殊的函数因此只有声明没有定义没有函数体。因此无法调用只能使用emit关键字发射。 【例子】点击按钮关闭窗口。 3.1 节的信号连接方式 本节强行在中间加一层自定义信号的转发过程。 上图中表示信号槽连接。 dialog.h #ifndef DIALOG_H
#define DIALOG_H#include QDialog
#include QPushButtonclass Dialog : public QDialog
{Q_OBJECTpublic:Dialog(QWidget *parent 0);~Dialog();
private:QPushButton *btn;
//自定义槽函数声明
private slots:void mySlot();
//自定义信号声明
signals:void mySignal();
};
#endif // DIALOG_Hdialog.cpp #include dialog.hDialog::Dialog(QWidget *parent): QDialog(parent)
{resize(500,500);btn new QPushButton(杀鸡用牛刀,this);btn-move(200,200);//第一次信号槽链接connect(btn,SIGNAL(clicked()),this,SLOT(mySlot()));//第二次信号槽链接connect(this,SIGNAL(mySignal()),this,SLOT(close()));
}
Dialog::~Dialog()
{//释放类对象堆空间delete btn;
}
void Dialog::mySlot()
{//发射信号emit mySignal();
} 步骤自定义信号无法调用只能发射信号因此在头函数内声明自定义信号和自定义槽函数在自定义槽函数内发射该自定义信号并调用相关槽函数。声明自定义槽函数和自定义信号需要connect连接多次 4、信号槽传参 【例子】点击按钮按钮上显式点击的次数。 // QPushButton的文字属性为text:QString可以使用setText更改按钮文字
// 参数:更新的文字
void setText(const QString text)正常解法非信号槽传参 dialog.h #ifndef DIALOG_H
#define DIALOG_H
#include QDialog
#include QPushButton
class Dialog : public QDialog
{Q_OBJECT
public:Dialog(QWidget *parent 0);~Dialog();QPushButton *btn;//自定义槽函数声明
private slots:void mySlot();
};
#endif // DIALOG_H dialog.cpp #include dialog.hDialog::Dialog(QWidget *parent): QDialog(parent)
{resize(500,500);//btn初始化 初始数据为”0“btn new QPushButton(0,this);btn-move(200,200);//connect 连接connect(btn,SIGNAL(clicked()),this,SLOT(mySlot()));
}
Dialog::~Dialog()
{delete btn;
}
void Dialog::mySlot()
{//静态局部变量static int count 0;count;//类型转换 int- QString整形转字符型number(形参)形参要转换的数据QString text QString::number(count);btn-setText(text);//更改按钮文字
} 信号槽传参法 把上面的案例强行改为信号槽传参 dialog.h #ifndef DIALOG_H
#define DIALOG_H
#include QDialog
#include QPushButton
class Dialog : public QDialog
{Q_OBJECT
public:Dialog(QWidget *parent 0);~Dialog();QPushButton *btn;//自定义槽函数声明
private slots:void mySlot();void mySlot2(int);//有参自定义槽函数
signals:void mySignal(int);//有参自定义信号函数
};
#endif // DIALOG_H dialog.cpp #include dialog.h
Dialog::Dialog(QWidget *parent): QDialog(parent)
{resize(500,500);btn new QPushButton(0,this);btn-move(200,200);//connect 连接connect(btn,SIGNAL(clicked()),this,SLOT(mySlot()));connect(this,SIGNAL(mySignal(int)),this,SLOT(mySlot2(int)));
}
Dialog::~Dialog()
{delete btn;
}
//自定义信号槽初始化
void Dialog::mySlot()
{//静态局部变量static int count 0;count;//发射带参数的自定义信号函数emit mySignal(count);
}
//自定义信号槽函数初始化注意传参
void Dialog::mySlot2(int count)
{//类型转化 int - QStringQString text QString::number(count);btn-setText(text);
} 需要注意的是 理论上可以传递任意多个参数建议最多写两个参数多了会很冗余。如果非得传多个参数的话可以定义成一个类传递对象。信号的参数个数必须大于等于槽的参数个数。信号的参数类型要与槽的参数类型匹配。 5、对应关系 5.1 一对多 一对多指的是一个信号连接多个槽函数。 dialog.h #ifndef DIALOG_H
#define DIALOG_H
#include QDialog
#include QDebug
#include QPushButton
class Dialog : public QDialog
{Q_OBJECT
public:Dialog(QWidget *parent 0);~Dialog();QPushButton *btn0;QPushButton *btn1;QPushButton *btn2;
private slots:void mySlot0();void mySlot1();void mySlot2();
};#endif // DIALOG_H dialog.cpp #include dialog.h
Dialog::Dialog(QWidget *parent): QDialog(parent)
{resize(500,500);btn0 new QPushButton(一对多,this);btn0-move(200,250);//一对多的优势是可以灵活处理每个对应关系//例如可以断开某个信号槽连接//断开连接的函数与连接函数传参一样只需要在前面加一个dis//disconnect(btn0,SIGNAL(clicked()),this,SLOT(mySlot0()));//一对多信号槽连接connect(btn0,SIGNAL(clicked()),this,SLOT(mySlot0()));connect(btn0,SIGNAL(clicked()),this,SLOT(mySlot1()));//一对一信号槽链接连接简单但处理不灵活btn1 new QPushButton(一对一,this);btn1-move(100,200);connect(btn1,SIGNAL(clicked()),this,SLOT(mySlot2()));
}
Dialog::~Dialog()
{delete btn0;
}
void Dialog::mySlot0()
{qDebug()A;
}
void Dialog::mySlot1()
{qDebug()B;
}
void Dialog::mySlot2()
{mySlot0();mySlot1();
} 在头文件内声明的函数可以以下操作在主函数内自定添加定义 5.2 多对一 多对一指的是多个信号连接同一个槽函数。多对一的问题在于槽函数无法直接判断那个信号触发的槽函数调用可以通过sender函数在槽函数中获得发射者对象通过对象对比判断来源。 dialog.h #ifndef DIALOG_H
#define DIALOG_H
#include QDialog
#include QPushButton
#include QDebug
class Dialog : public QDialog
{Q_OBJECT
public:Dialog(QWidget *parent 0);~Dialog();QPushButton *btn1;QPushButton *btn2;
private slots:void btnClickedSlot();
};
#endif // DIALOG_H dialog.cpp #include dialog.h
Dialog::Dialog(QWidget *parent): QDialog(parent)
{resize(500,500);btn1 new QPushButton(多对一A,this);btn1-move(200,200); btn2 new QPushButton(多对一B,this);btn2-move(300,300); // 多对一连接connect(btn1,SIGNAL(clicked()),this,SLOT(btnClickedSlot()));connect(btn2,SIGNAL(clicked()),this,SLOT(btnClickedSlot()));
}
Dialog::~Dialog()
{delete btn1;delete btn2;
}
void Dialog::btnClickedSlot()
{// 通过sender函数获取发射者对象if(sender() btn1){qDebug() A ;}else if(sender() btn2){qDebug() B ;}else{qDebug() 对象错误 ;}
}