如何自学qt(1)

【题目应该叫,如何在面试的前一天临时抱佛脚】
【抱佛脚失败】

1,文件目录

在这里插入图片描述
项目名称
——pro文件,里面有基础的版本信息,一般不改
——头文件,和c++一样,自动生成
——资源文件
main.cpp :程序入口
mainwindow : 窗体文件,代码在里面
——组成
里面放着ui

2,写代码!

①写个摁钮吧
两种写法,一种是

QPushButton *b = new QPushButton();

然后在后面设定

b  -> setParent(this); //继承的窗体
b -> setText("first");  //摁钮内容

或者直接就

QPushButton *b =  new QPushButton("first",this);

②一些基础的函数

setFixedSize(400,500); // 设置窗体大小
resize(100,100); //设置摁钮初始位置
b -> move(200,100); //改变b摁钮的位置
setWindowTitle("firstwindow"); //修改窗体名称
b -> resize(100,100);

3,对象树

【别人的对象都有树啦!】
qt里的存储方式是对象树——被继承的窗体为父节点,新创建的构件是子节点,这样,如果删除一个父节点,下面的构件就可以自行删除。
【所以,在代码里不用删除new的对象】
注意,和c++一样,对象树的构建从上到下,析构从下到上
4,信号与槽【据说这是qt的核心问题】
connect(信号的发送者,发送的具体信号,信号的接受者,信号的处理(槽函数))
信号槽的优点:松散耦合,发送端和接收端本来是没有优点的
具体的写一个

connect(c,&QPushButton :: clicked,this,&MainWindow :: close);
//记得要加&

5,自定义信号与槽

①信号
信号写在发送端的头函数里,signals下,返回值是void,可有参数,不需要实现。
比如

signals:
void hungry();

②槽函数
槽函数的声明写在接收端的头文件slot中,返回值是void,可有参数,需要被实现。
比如

person.h
public slots:
    void treat();
person.c
void person::treat()
{
    qDebug << "给它恰!";
}

③在窗体函数里生成两个对象
【能不能给我生成一个对象】
【要声明哦】

mainwindow.h
private:
person *p;
dog *d;
mainwindow.c
this -> p = new Person(this);
this -> d = new Dog(this);

④做连接
这个连接,不是一时的冲动,是长长久久的连接
格式同上部分,直接给代码啦

connect(d,&Dog::hungry(),p,&Person::treat());

⑤做行动,触发连接
像普通的函数一样
在窗体的头文件里声明,在.c里面实现并调用
具体代码如下

MainWindow.h
private void morning();
MainWindow.c
void MainWindow::morning()
{
    emit d -> hungry();
}
MainWindow::MainWindow()
{
    ……
    connect(d,&Dog::hungry(),p,&Person::treat());
    morning();
}

这样就可以成功触发啦!

关于信号与槽的重载

信号和槽都是可以带参数的,比如我们在狗狗类里设置这样一个信号,跟之前的函数放在一起

dog.h
void hungry();//之前的
void hungry(QString food);

相同的,在主人类中

person.h
void treat();//之前的
void treat(QString food);

槽是要实现的

void Person::treat()//之前的
{
    qDebug()<< "喂食";
}
void Person::treat(QString food)
{
	qDebug()<< "喂食" << food;
}

嗯……之后调用触发

MainWindow.c
void MainWindow::morning()
{
	emit d -> hungry("meat");
}

然而现在并不能实现,因为每个函数我都设置了带参和不带参的两个同名函数,所以,这个时候需要函数指针出场。

void(Dog :: *dogsignal)(QString) = &Dog :: hungry();
void(Person :: *personslot)(QString) = &Person :: treat();
connnect(d,dogsignal,p,personslot);

这样就解决了信号槽的重载问题
嗯……还有一个小问题,在person中带参信号传递那里
如果我们这么写,出来的结果是在这里插入图片描述
混入了一个""
原因大概是QString屏幕打印的问题,要把它转化成char*
方法如下

void Person::treat(QString food)
{
    qDebug()<< "喂食" << food.toUtf8().data();
}

信号触发信号

想做一个名为早上的摁钮,点击触发主人喂食
首先写一个摁钮,方法和第一部分一样

MainWindow.c
QPushButton *b = new QPushButton("morning",this);
b -> resize(100,80);

比较复杂的办法是再写一个连接,摁钮点击连接morning函数,然后morning函数跟之前一样,触发狗狗饿了,这里不提。
我们搞一个快捷一点的,用信号触发信号

MainWindow.c
void(Dog::*dogsignal2)(void) = &Dog::hungry;
void (Person::*personslot2)(void) = &Person::treat;
connect(d,dogsignal2,p,personslot2);
connect(b,&QPushButton::clicked,d,dogsignal2);

顺便一提,断开信号是用disconnect,后面的参数和connect相同。

信号槽相关扩展

1,一个信号可以连接多个槽函数
2,信号和槽可以是多对多的关系
3,信号和槽函数的参数,必须类型一一对应
4,信号和槽的参数数量可以不同,但只能是信号的参数数量大于槽的参数数量。
所以刚刚要用无参数的槽匹配点击摁钮信号,因为那个信号函数参数是bool,数量是1,如果用有参数的那个,不适配。
5,qt4.0中的连接简便写法
非常之简单

connect(d,SIGNAL(hungry()),p,SLOT(treat()));

但是有一定的缺陷,不建议使用。

lambda表达式

我曾经在之前写上升下降字符串里面提过匿名函数的写法,这里再细致的写一点。
所谓匿名函数,就是在函数内部再写一个函数,特点是易于传参和节省空间。
【缺点是,一般情况下,我都记不得要用它……】
格式如下

auto  func = [] (int i)
{
//函数内容
};

在这里,我们把它塞进信号里,所以就不用搞返回值,直接用基础格式就完事了。
基础格式:[] () {};
非常之简洁和好记——第一个中括号表示匿名函数的身份,第二个传参(可不传),第三个里面写函数主体。
这个东西,非常好用!因为可以在函数里面写多个槽,还可以触发传参不匹配的槽!
例子如下,前文和之前一样,主人和狗狗
注意:当使用值传递时,如果要改变参数的值,要加入mutable参数,不然会报错。
mutable在()后。

connect(b,&QPushbutton::clicked,this,[=]()
{
    this -> close();
    emit d -> hungry();
});

【一般都用=,不用&】

第一章作业

写一个窗体,里面有两个摁纽,一个写open,一个写close
点击open出现另一个窗体,点击close关闭

代码如下:
【我先用添加文件创建了一个窗体,叫dialog】

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    QPushButton *op = new QPushButton("open",this);
    op -> move(50,100);
    QPushButton *cl = new QPushButton("close",this);
    cl -> move(200,100);
    Dialog *d = new Dialog();
    d -> move(300,200);
    connect(op,QPushButton::clicked,d,[=](){d -> show();});
    connect(cl,QPushButton::clicked,d,[=](){d -> close();});
}
  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值