qt信号和槽与对话框

信号和槽

1.信号和槽:
在生成一个按钮之后,如果没有后续的操作,那么这个按钮就像是摆设一样,而槽(后续的操作)没有信号的触发,也无法执行,因此需要一个函数将信号和槽进行连接:

//(信号的发送者,发送的信号,信号的接受者,信号的处理(槽));四个参数都是地址形式,其中参数2和参数4前边要加上“&”;
connect(mybtn,&QPushButton::cliicked,this,&QWidget::close);

信号和槽具有松散耦合的特点,也就是说信号和槽之间是相互独立的,需要连接才可以实现一种操作,而一个槽可以由不同的信号触发,比如说上述代码中点击按钮关闭窗口的操作,我可以通过这个按钮关闭,也可在别的地方通过点击别的按钮或者其他操作来关闭窗口。

2.自定义的信号和槽,以小明请小花吃饭为例,小花是信号的发出者,发出信号他饿了,小明是信号的接收者,请吃饭就是小明的对这个信号的处理,
新建一个项目,在项目中添加连个类,一个类级叫做teacher,一个类叫做student,两个类都不需要依附于对话框之类的,所以父类继承Qobject即可,由于老师是信号的发出者,所以在老师类的.h文件中的signals:下添加信好,void hungry();并且这个信号不需要实现,学生是信号的接受者,所以在学生类(qt5,4版本以后可以添加在public或者public sloits下边)的public:下添加槽函数void
treat();并且需要在.cpp文件实现。然后在主窗口类的私有成员中声明学生对st,和老师对象zt,在.cpp文件中对st,zt进行初始化:(分配内存空间)

zt=new Teacher(this);
st=new Student(this);

在主窗口函数中声明并实现一个函数叫做classIsOver();作用是用来触发老师饿了的函数,

void MainWindows::classIsOver()
{
	qDebug()<<"老师请学生吃饭"<<endl;
}

然后将信号和槽进行连接

connect(zt,&Teacher::hungry,st,&Stundent::treat());

此时信号和槽已经连接,但是信号还没有被触发,再补上触发函数classIsOver();

classIsOver();

运行程序会看到在下边的Debug模块上显示 了“老师请学生吃饭”

3.自定义的信号和槽发生重载的解决
在这里插入图片描述上图中的报错是因为在信号和槽进行连接时出现了重载的信号或槽。
比如说定义了两个槽函数
3.1

void treat()
{
	qDebug<<"1111";
}
void treat(QString str)
{
	qDebug<<"2222";
}

此时应该用函数指针来解决,定义一个函数的指针,让它指向其中一个函数的地址,在进行信号和槽的连接时,使用这个已经被定义好的函数指针所在地址,

//在声明成员函数的指针的时候,要将成员函数的作用域也加入进去,比如Teacher::*ip,
//后边跟随的括号中填写的是参数类型
void(Teacher::*ip1)(QString)=&Teacher::hungry;
void(Student::*ip2)(QString)=&Student::treat;
connect(zt,ip1,st,ip2);
classIsOver();

另外,connect会自动将信号函数的所有参数传递给槽函数。所以发送信号和槽函数都需要重载.

3.2信号和信号的连接
connect不仅可以实现信号和槽的连接,也可以实现信号和信号的连接,但需要注意的是,由于connect是将参数从前传递到后边,所以应该保证前后的信号发送和槽函数/信号发送2所具有的参数是一样的,因此,假如我想加入一个按钮实现点击这个按钮,老师就饿了,由于按钮点击按钮函数是不需要传递参数的,所以老师饿了的函数也应该用无参的

	//定义函数指针
    void(Student::*stuip1)()=&Student::treat;
    void(Student::*stuip2)(QString)=&Student::treat;

    void(Teacher::*ip1)()=&Teacher::hungry;
    void(Teacher::*ip2)(QString)=&Teacher::hungry;

    connect(zt,ip1,st,stuip1);
    //connect(zt,ip2,st,stuip2);
    //点击按钮触发下课
    //connect(ui->pushButton,&QPushButton::clicked,this,&MainWindow::classIsOver);
    //信号连接信号
    connect(ui->pushButton,&QPushButton::clicked,zt,ip1);

    //QPushButton *btn=new QPushButton("上课",this);
    //connect(btn,&QPushButton::clicked,zt,ip1);

    //信号连接信号
    classIsOver();

同理也有disconnect()函数,用法和connect()函数一样,作用是断开信号连接。

Lambda表达式

形容}{}的就是lambda表达式,又叫做匿名函数,可以用于信号和槽的一些函数使得一些操作非常的方便。

  1. []标识符 匿名函数
    1.1 []中添加“=”,值传递(推荐)
    1.2 []中添加“&",引用传递(不推荐)
  2. ()参数
  3. {}实现体
  4. mtable,写在()的后边,表示可以对传入进来的变量进行修改
  5. 样例1:
    由于按钮点击信号后边对应的槽函数只能是无参的(因为按钮点击信号没有参数,所以传递过去的也没有参数),所以如果想通过点击按钮,同时槽函数使用带参的便可以使用匿名函数
 	QPushButton *btn2=new QPushButton(this);
    btn2->move(100,100);
    btn2->resize(100,100);
    btn2->setText("吃饭");
    connect(btn2,&QPushButton::clicked ,this,[=](){
        //this->close();
        emit st->treat("宫保鸡丁");
    });

样例2:

//值传递
   int t=1;
   [=]()mutable {
       t+=100;
       qDebug()<<"匿名函数里边的"<<t;
   }();//注意加上这个小括号就像函数一样。
   qDebug()<<"匿名函数外边的"<<t;
   qDebug()<<"\n";
//引用传递
   int s=1;
   [&s]()mutable {
       s=s+100;
       qDebug()<<"匿名函数里边的"<<s;
   }();
   qDebug()<<"匿名函数外边的"<<s;
}

值传递的结果是:101,1;
引用传递的结果是:101,101;
l

模态和非模态对话框的创建

在创建ui界面之后,想要通过点击菜单栏中的新建按钮弹出一个对话框
在这里插入图片描述
使用connect函数

//triggered是菜单栏,工具栏上按钮的触发函数,被定义在QAction类中
connect(ui->actionnew,&QAction::triggered,[=](){
	//创建模态对话框
	Dialog *dialog(this);//在栈区创建.调用完毕立即释放
	dialog.resize(114,514);
	dialog.exec();//创建模态对话框使用的函数,阻塞功能,窗口弹出后会停留在这,不会继续向下执行直到对话框关闭为止。
});
connect(ui->actionnew,&QAction::triggered,[=](){
	//创建非模态对话框
	Dialog *dialog2=new Diallog(this);
	//将对象放在堆区使对象一直存活,防止窗口一闪而过。
	dialog2->resize(200,100);
	//显示对话框
	dialog2->show();
	//为了防止可能出现的内存泄露,设置dialog2的属性为WA_DeleteOnClose的含义是:每次只要关闭了对话框,
	//就将对话框对象所分配的内存释放掉。(因为如果不这样做,当多次点击创建对话框对象并且没有关闭主窗口		       时,创建对话宽对象所分配的内存一直不被释放,当这样的操作次数过多会造成内存泄露,因此设置只要关闭对话框,就将对话框对象所分配的内存释放掉)
	dialog2->setAttribute(Qt::WA_DeleteOnClose);
});

消息对话框

消息对话框QMessageBox 类提供一个模态的对话框来通知一些信息,或者向用户提出一个问题并且获取答案等。比如,点击按钮弹出一个对话框,对话框分四种(错误(critical),信息(information),提问(information),警告(waring))。
在connect中通过匿名函数实现:
比如QMessageBox::question(this,“question”,“问题”,QMessageBox::Save | QMessageBox::Cancel,QMessageBox::Cancel);
参数1:父亲
参数2:标题栏内容
参数3:描述
参数4:按键类型
参数5:默认关联回车的按键
参数5通常在question中才有意义,因为有两个按键,而其他的对话框只有一个按键,默认关联回车的只能是那一个键,所以参数5通常省略。

connect(btn3,&QPushButton::clicked,this,[=](){
        //QMessageBox::critical(this,"crticial","错误");
        //QMessageBox::information(this,"information","信息");
       //对话框返回的是一个int值,可以用一个int变量来接收。
         int ret=QMessageBox::question(this,"question","问题",QMessageBox::Save | QMessageBox::Cancel,QMessageBox::Cancel);
         switch(ret)
         {
             case QMessageBox::Save:
                 qDebug()<<"点击了保存按钮";
                 break;
             case QMessageBox::Cancel:
                qDebug()<<"点击了取消按钮";
                break;
         }
         /*if(QMessageBox::Save==QMessageBox::question(this,"question","问题",QMessageBox::Save | QMessageBox::Cancel,QMessageBox::Cancel)){
             qDebug()<<"点击了保存按钮";
         }
         else
             qDebug()<<"点击了取消按钮";
        */
        //QMessageBox::warning(this,"warning","警告");

   });
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

黒猫.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值