无锡网站维护公司,月付网站空间提供商,济南seo网站排名关键词优化,做谐和年龄图的网站文章目录 1、简介2、代码实现2.1 界面菜单“转到槽”方法2.2 界面信号槽编辑器方法2.3 QT4.0的绑定方法2.4 QT5.0之后的绑定方法2.5 C11的方法2.6 lamda表达式方法2.7 QSignalMapper方法 结语 1、简介
在GUI编程中#xff0c;当我们更改一个小部件时#xff0c;我们通常希望… 文章目录 1、简介2、代码实现2.1 界面菜单“转到槽”方法2.2 界面信号槽编辑器方法2.3 QT4.0的绑定方法2.4 QT5.0之后的绑定方法2.5 C11的方法2.6 lamda表达式方法2.7 QSignalMapper方法 结语 1、简介
在GUI编程中当我们更改一个小部件时我们通常希望通知另一个小程序。更普遍地说我们希望任何种类的物体都能够相互通信。例如如果用户单击“关闭”按钮我们可能希望调用窗口的Close()函数。
其他工具包使用回调实现这种通信。回调是指向函数的指针因此如果您希望处理函数通知您某个事件您可以将指向另一个函数的指针回调传递给处理函数。然后处理函数在适当的时候调用回调。虽然使用这种方法的成功框架确实存在但回调可能是非直观的并且在确保回调参数的类型正确性方面可能会遇到问题。
在Qt中我们有一种替代回调技术的方法我们使用信号和槽。当特定事件发生时会发出一个信号。Qt的小部件有许多预定义的信号但我们总是可以对小部件进行子类化以向它们添加我们自己的信号。槽是响应于特定信号而调用的函数。Qt的小部件有许多预定义的插槽但通常的做法是对小部件进行子类化并添加自己的插槽以便处理您感兴趣的信号。 信号与槽是用于对象之间的通信的这是 Qt 的核心。为此 Qt 引入了一些关键字他们是slots、signals、emit这些都不是 C关键字是 Qt 特有的这些关键字会被 Qt 的 moc转换为标准的 C语句。
连接规则 1、信号参数可以比槽函数多反之则不可以 2、 一个信号可以连接多个槽 3、多个信号可以连接到一个槽 4、一个信号可以与另一个信号连接
2、代码实现
2.1 界面菜单“转到槽”方法
使用这种方法我们不需要使用connect函数将信号与槽函数做连接。 这里槽函数的命名有一定的规则一般是 on_objectname_signal 这样来命名的。 不需要使用 connect 函数可以通过Qt Creator 界面来完成发送信号和槽函数的连接。在按钮上鼠标右键弹出菜单选择“转到槽…”如下 弹出小窗口选择“clicked()”后确定。 然后在文件里自动生成代码如下
mainwindow.h
private slots:void on_pushButton_clicked();mainwindow.cpp
void MainWindow::on_pushButton_clicked()
{QMessageBox::information(this, , on_pushButton_clicked);
}我们也可以完全在代码里实现这种方式
mainwindow.h
private slots:void on_myButton_clicked();mainwindow.cpp
MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{ui-setupUi(this);QPushButton *button new QPushButton(this); // 创建按钮button-setObjectName(myButton); // 指定按钮的对象名ui-setupUi(this); // 要在定义了部件以后再调用这个函数
}
void Widget::on_myButton_clicked() // 使用自动关联
{close();
}2.2 界面信号槽编辑器方法
打开信号槽编辑界面添加记录设置相关参数。 在mainwindow.ui界面定义文件中会自动生成对应的代码可以手动修改。
2.3 QT4.0的绑定方法
Qt4使用了SIGNAL和SLOT这两个宏将信号和槽的函数名转换成了字符串。使用字符串导致了Qt4有以下缺点一旦出现连接不成功的情况Qt 4 是没有编译错误的
connect(obj1, SIGNAL(fun1(param1, param2,...)), obj2, SLOT(fun2(param1,...)));优点对所有控件都适用。 缺点书写繁琐槽函数必须在slots标签下。
1和控件有关系的信号槽
mainwindow.h
private slots:void pushButon1_clicked();void onTextEdited(QString);mainwindow.cpp
MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{ui-setupUi(this);connect(ui-pushButton,SIGNAL(clicked()),this,SLOT(pushButon1_clicked()));connect(ui-lineEdit, SIGNAL(textEdited(QString)), this, SLOT(onTextEdited(QString)));
}void MainWindow::pushButon1_clicked()
{QMessageBox::information(this, , pushButon1_clicked);
}void MainWindow::onTextEdited(QString s)
{qDebug() s;
}2和控件无关系的信号槽
mainwindow.h
signals: //信号void mySignal_1(int a);void mySignal_2(int a, float b);private slots: //槽void mySlot_1(int b);void mySlot_2(int b);mainwindow.cpp
MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{ui-setupUi(this);//信号槽connect(this,SIGNAL(mySignal_1(int)),this,SLOT(mySlot_1(int)));connect(this, SIGNAL(mySignal_2(int, float)), this, SLOT(mySlot_2(int)));
}
void MainWindow::mySlot_1(int b)
{QString str QString::number(b);QMessageBox::information(this, 1, str);
}
void MainWindow::mySlot_2(int b)
{QString str QString::number(b);QMessageBox::information(this, 2, str);
}
void MainWindow::test()
{//发送信号emit mySignal_2(5, 2.2);emit mySignal_1(123);
}注意在不进行参数传递时信号槽绑定时也是要求信号的参数数量大于等于槽函数的参数数量。这种情况一般是一个带参数的信号去绑定一个无参数的槽函数。
2.4 QT5.0之后的绑定方法
Qt 5 推出了新的 connect 函数不需要使用 SIGNAL() 和 SLOT() 宏可以在编译时做类型检查。
mainwindow.h public:void textChanged(QString);void pushButon1_clicked();mainwindow.cpp
MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{ui-setupUi(this);connect(ui-pushButton,QPushButton::clicked,this,::MainWindow::pushButon1_clicked);connect(ui-lineEdit, QLineEdit::textEdited, this, MainWindow::textChanged);void(MainWindow:: *buttonClickSlot)() MainWindow::pushButon1_clicked;void(MainWindow:: *textEditedSlot)(QString) MainWindow::textChanged;connect(ui-pushButton, QPushButton::clicked, this, buttonClickSlot);connect(ui-lineEdit, QLineEdit::textEdited, this, textEditedSlot);
}void MainWindow::pushButon1_clicked()
{QMessageBox::information(this, , pushButon1_clicked);
}
void MainWindow::textChanged(QString s)
{qDebug() s;
}connect()函数基于函数指针的重载形式
[static] QMetaObject::Connection QObject::connect(const QObject *sender, PointerToMemberFunction signal,
const QObject *receiver,
PointerToMemberFunction method,
Qt::ConnectionType type Qt::AutoConnection)注意这是QT5中加入的一种重载形式指定信号和槽两个参数不再使用SIGNAL()和 SLOT()宏并且槽函数不再必须是使用slots关键字声明的函数可以是任意能和信号关联的成员函数。要使一个成员函数可以和信号关联那么这个函数的参数数目不能超过信号的参数数目但是并不要求该函数拥有的参数类型和信号中对应的参数类型完全一致只需要可以进行隐式转换即可。
connect(dlg, myWindwow::test1, this, myWidget::test2);2.5 C11的方法
mainwindow.cpp
MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{ui-setupUi(this);connect(ui-pushButton, QOverloadbool::of(QPushButton::clicked),this,::MainWindow::pushButon1_clicked);
}void MainWindow::pushButon1_clicked()
{QMessageBox::information(this, , pushButon1_clicked);
}2.6 lamda表达式方法
还支持C11 中的lambda表达式可以在关联时直接编写信号发射后要执行的代码。使用 Lambda表达式的好处是代码的书写更加方便快捷。在connect 函数中槽函数参数我们可以改用Lambda表达式的方式来进行传参。
使用Lambda表达式我们就不需要在类中对槽函数做任何的声明了。Lambda表达式是C 11的内容在比较低的 Qt版本中要注意在Pro项目文件中加入 CONFIG C 11。
connect(dlg, MyWindow::test1, [ ](int value){ui-label-setText(tr(获取的值是%1)arg(value));
});mainwindow.cpp
MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{ui-setupUi(this);connect(ui-pushButton, QOverloadbool::of(QPushButton::clicked),[](){QMessageBox::information(this, , lamda表达式绑定成功);});connect(ui-pushButton, QPushButton::clicked, this, [](){this-close();});connect(ui-lineEdit, QLineEdit::textEdited, this, [](QString s){qDebug() s;});
}或
MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{ui-setupUi(this);connect(ui-pushButton, QPushButton::clicked, this, [](){QMessageBox::information(this, , lamda表达式绑定成功2);});
}2.7 QSignalMapper方法
QSignalMapper类收集了一系列的无参信号然后使用相对于信号发送者来说的整数、字符串或控件参数来重新发送它们。
QSignalMapper类支持使用setMapping()函数将一个特定的整数或字符串和一个特定的对象关联起来。 可以将对象的信号(比如button的clicked)连接到QSignalMapper对象的map()槽函数上而map()槽函数又会使用与对象相关联的整数或字符串来发送mapped()信号。
QSignalMapper类可以看成是信号的翻译和转发器。 它可以把一个无参的信号翻译成带int参数、QString参数、 QObject* 参数或者QWidget *参数的信号并将之转发。
QSignalMapper类的功能核心是要建立一个从原始信号的object到需要的数据的映射setMapper函数。 map()作为QSignalMapper的一个槽函数将根据setMapping规则转发mapped()信号。 QSignalMapper可将多个有类似处理方式signal用一个slot实现相当于将N个一对一映射通过集中转换成多对一映射。
mainwindow.h
#include QSignalMapperprivate:
Ui::MainWindow *ui;
QSignalMapper * myMapper;private slots:void showLabel(int i);mainwindow.cpp
MainWindow::MainWindow(QWidget *parent) :QMainWindow(parent),ui(new Ui::MainWindow)
{ui-setupUi(this);myMapper new QSignalMapper();//新建一个按钮数组id为push[i]QPushButton * push[5];for (int i 0; i 5; i){push[i] new QPushButton(this);push[i]-setGeometry(300, 60 30 * i, 90, 24);push[i]-setText(QString(button%1).arg(i));connect(push[i], SIGNAL(clicked()), myMapper, SLOT(map()));myMapper-setMapping(push[i], i);}connect(myMapper, SIGNAL(mapped(int)), this, SLOT(showLabel(int)));
}void MainWindow::showLabel(int i)
{ui-label-setText(QString(button%1 is clicked).arg(i));
}结语
如果您觉得该方法或代码有一点点用处可以给作者点个赞或打赏杯咖啡╮(▽)╭ 如果您感觉方法或代码不咋地//(ㄒoㄒ)//就在评论处留言作者继续改进o_O??? 如果您需要相关功能的代码定制化开发可以留言私信作者(✿◡‿◡) 感谢各位童鞋们的支持( ´ ▽´ ) ( ´ ▽´)っ