Qt中的信号和槽以及自定义对话框

一、信号和槽

     Qt中使用信号和槽机制来完成对象之间的协同操作,信号和槽都是函数,例如,单击窗口上的一个按钮时,想要弹出一个对话框,那么可以将这个按钮的单击信号和自定义的槽关联起来,在这个槽中创建一个对话框并且显示它。这样单击信号时就会发射信号,进而执行槽来显示一个对话框。

例子:

1、信号和槽的手动关联

(1)在Qt Creator上新建一个项目,选择 文件——新建文件或项目——Application——Qt Widgets Application,项目名为mydialog1,基类选择QWidget,类名为MyWidget。双击mywiget.ui文件,在设计模式中往界面添加一个Label和一个Push Button,在属性栏中将Push Button的objectName改为showChildButton,然后更改Label的显示文本为“我是主界面!”,更改按钮的显示文本为“显示子窗口”。



(2)双击mywidget.h文件,在MyWidget类声明的最后添加槽的声明

public slots:
void showChildDialog();
这里自定义了一个槽,槽一般使用slots关键字进行修饰(Qt4中必须使用,Qt5中使用新的connect语法时可以不用,为了与一般函数进行区分,建议使用),这里使用的public slots,表明这个槽可以在类外被调用。

(3)到源文件中编写这个槽的实现代码

Qt Creator提供了一个快速添加定义的方法:在showChildDialog函数上右击,在弹出的级联菜单中选择Refactor菜单项,然后点击“在mywidget.cpp添加定义”,确认后,编辑器会转到mywidget.cpp文件中,并且已自动创建了showChildDialog()槽的定义。这种方法也用于先在源文件中添加,然后自动在头文件中添加声明。

mywidget.cpp文件中将showChildDialog()槽的实现更改如下:

void MyWidget::showChildDialog()
{
    QDialog *dialog = new QDialog(this);
    dialog->show();
}

(4) 更改MyWidget类的构造函数

MyWidget::MyWidget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::MyWidget)
{
    ui->setupUi(this);
    connect(ui->showChildButton,&QPushButton::clicked,this,&MyWidget::showChildDialog)
}

这里使用了connect()函数将按钮的单击信号clicked()与新建的槽进行关联,这是信号和槽的手动关联方式。clicked()信号在QPushButton类中定义,而connect()是在QObject类中定义的函数,以为MyWidget类继承自QObject,所以可以直接使用。

connect函数的4个参数为:发射信号的对象发射的信号接受信号的对象要执行的槽

程序运行结果:


2、信号和槽的自动关联

自动关联就是将关联函数整合到槽命名中,前面定义的槽可以重命名为on_showChildButton_clicked()就是由字符on、发射信号的部件对象名和信号组成。

(1)打开mywidget.cpp文件,删除上文定义的connect()函数,然后更改showChildDialog()槽的名字。Qt Creator提供了一个快速更改名字的方法:在原函数上右击,在弹出的级联菜单中选择Refactor,然后选择Renname Symbol Under Cursor,更改为on_showChildButton_clicked(),这时源文件和头文件中相应的函数都进行了更改,这就是信号和槽的自动关联。

void MyWidget::on_showChildButton_clicked()
{
    QDialog *dialog = new QDialog(this);
    dialog->show();
}
运行程序结果和上述相同。

在编写程序时一般使用第一种connect手动关联方式。

二、自定义对话框

基于上面的项目基础上进行自定义对话框的设计。

1、添加自定义对话框

项目——右键添加新文件——Qt——Qt设计师界面类,界面模板选择Dialog without Buttons,类名改为MyDialog,然后在设计模式想窗口添加2个Push Button,分别更改为“进入主界面”和“退出程序”。


2、设计信号和槽

下面使用两种方法进行信号和槽关联:

(1)使用设计器实现“退出程序”按钮信号和槽的关联(第一种方法

进入设计界面,单击设计器上方的Edit Signals/Slots图标(或者按下F4),进入部件信号和槽的编辑模式。在“退出程序”按钮上单击鼠标左键,按住拖动至窗口界面上,松开左键,在弹出的配置链接对话框中,选择“显示从QWidget继承的信号和槽”,在左边的QPushButton栏中选择信号clicked(),右边QDialog栏中选择对应的槽close(),完成单击OK。



 这时“退出程序”按钮的单击信号就和对话框中的关闭操作槽进行了关联。取消直接在界面上右键删除。关联好后,按下F3回到部件编辑模式。

(2)设置“进入主界面”按钮的信号和槽的关联(第二种方法:在设计器中直接进入相关信号的槽

在“进入主界面”按钮上单击右键,在弹出的级联菜单中选择“转到槽”,然后在弹出的对话框中选择clicked()信号,单击OK,这时便会进入代码编辑模式,并且定位到自动生成的on_pushButton_clicked()槽中。在设计器中添加的部件要使用信号和槽,一般会使用此种方法。


在槽的函数定义下添加代码(mydialog.cpp文件):

void MyDialog::on_pushButton_clicked()
{
    accept();
}
accept()函数是QDialog类中的一个槽,对于使用exec()函数实现模态对话框,执行这个槽会隐藏这个模态对话框,并返回QDialog::Accepted值,这个值被用来判断哪个按钮被按下了。

3、在主界面中使用自定义的对话框

(1)更改main.cpp

#include "mywidget.h"
#include <QApplication>
#include"mydialog.h"       //要把头文件添加进来,因为使用了MyDialog类
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MyWidget w;
    MyDialog dialog;      //新建MyDialog类对象
    if(dialog.exec() == QDialog::Accepted)  //判断dialog的exec()的返回值,如果按下了“进入主界面”,则返回值是QDialog::Accepted,则往下执行显示
    {
    w.show();           //如果是按下了"进入主界面"按钮,则显示主界面
    return a.exec();    //程序正常运行
    }
    else return 0;      //否则,退出程序
}
上述已实现从登录对话框到主界面,再从主界面显示一个对话窗口的应用。

(2)实现从主界面重新进入登录界面的功能

双击mywidget.ui文件,在设计模式中向界面添加两个Push Button,显示文本分别为“重新登陆”和“退出”,然后使用上述信号和槽的关联方法,将“退出”按钮的clicked()信号和MyWidget界面的close()槽关联;再转到“重新登陆”按钮的clicked()信号和槽,更改mywidget.cpp文件如下:

#include "mywidget.h"
#include "ui_mywidget.h"
#include"mydialog.h"
MyWidget::MyWidget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::MyWidget)
{
    ui->setupUi(this);
}

MyWidget::~MyWidget()
{
    delete ui;
}

void MyWidget::on_showChildButton_clicked()
{
    QDialog *dialog = new QDialog(this);
    dialog->show();
}

void MyWidget::on_pushButton_clicked()
{
    close();  //先关闭主界面,其实它是隐藏起来了,并没有真正的退出,
    MyDialog dlg;               //用到MyDialog,故前面要加#include"mydialog.h",新建MyDialog类对象为dlg
    if(dlg.exec() == QDialog::Accepted)  //此时是在“进入主窗口”和“退出程序”的界面,
        show();            //如何再次检测到“进入主界面”按下按钮的信号,则再次显示主界面
}               //否则,若是其他信号,则程序将退出

close()槽的说明:

  它不一定使程序退出,只有当只剩下最后一个主界面(就是没有父窗口的界面),这时调用close()槽,程序才会退出;而其他情况下,界面只是隐藏起来,并没有销毁。

程序运行结果:



单击“进入主界面”按钮:


单击“重新登陆”按钮:返回到登陆界面



猜你喜欢

转载自blog.csdn.net/gaoyu1253401563/article/details/79235377