作业:
实现登录界面,设置账号为admin,密码为123456,登陆成功则退出当前界面,切换到其他界面,密码错误或者账号不匹配则清空账号密码输入框中的内容,并输出登录失败,点击取消则退出当前登录界面
登录界面的头文件:
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QLineEdit>//行编辑器
#include<QIcon>//图标
#include<QLabel>//标签
#include<QPushButton>//按钮
#include<QIcon>//图标
#include<QDebug>//调试函数
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = nullptr);
~Widget();
QLabel *lab1;
QLabel *lab2 ;
QLabel *lab3 ;
QLineEdit *dit1;
QLineEdit *dit2 ;
QPushButton *btn1;
QPushButton *btn2;
public slots:
void btn1_slot(); //自定义一个按钮1的槽函数
signals:
void jump(); //定义跳转函数
};
#endif // WIDGET_H
登录界面的实现函数:
#include "widget.h"
Widget::Widget(QWidget *parent)
: QWidget(parent)
{
this->setFixedSize(500,600);//设置窗口固定大小尺寸
this->setWindowTitle("来也匆匆");//设置窗口标题
this->setWindowIcon(QIcon(":/photo/ckbq.jpg"));//设置窗口图标
this->setStyleSheet("background-color:purple");//设置窗口颜色
lab1 = new QLabel(this);//创建一个标签,设置父组件为当前窗口组件
lab1 -> resize(500,200);//设置标签大小
lab1 -> setPixmap(QPixmap(":/photo/bj.jpg"));//标签中添加图片内容
lab1 -> setScaledContents(true);//设置标签内容自适应
lab2 = new QLabel(this);//创建标签,设置父组件为当前窗口组件
lab2 -> resize(40,40);//设置标签大小
lab2 -> move(120,300);//设置标签位置
lab2 -> setPixmap(QPixmap(":/photo/userName.jpg"));
lab2 -> setScaledContents(true);//设置内容自适应
lab3 = new QLabel(this);//创建标签,设置父组件为当前窗口组件
lab3 -> resize(40,40);//设置标签大小
lab3 -> move(lab2->x(),lab2->y()+100);//设置标签位置
lab3 -> setPixmap(QPixmap(":/photo/passwd.jpg"));
lab3 -> setScaledContents(true);//设置标签内容自适应
dit1 = new QLineEdit(this);//创建一个行编辑器,指定父组件
dit1->setPlaceholderText("QQ/手机/邮箱");//设置占位文本
dit1->move(lab2->x()+70,lab2->y());//设置行编辑器位置
dit1->resize(250,40);//设置行编辑器大小
dit1->setStyleSheet("background-color:white");//设置背景颜色
dit2 = new QLineEdit(this);//创建一个行编辑器,父组件为当前窗口组件
dit2->setPlaceholderText("密码");//设置占位文本
dit2->move(lab3->x()+70,lab3->y());
dit2->resize(250,40);//设置行编辑器大小
dit2->setStyleSheet("background-color:white");//设置背景颜色
dit2->setEchoMode(QLineEdit::Password);//设置输入为密文模式
btn1 = new QPushButton("登录",this);//创建一个按钮,设置按钮文本为登录
btn2 = new QPushButton("取消",this);//创建一个按钮,设置按钮文本为取消
btn1->resize(80,40);//设置按钮大小
btn2->resize(80,40);//设置按钮大小
btn1->move(300,500);//设置按钮位置
btn2->move(btn1->x()+100,btn1->y());//设置按钮位置
btn1->setIcon(QIcon(":/photo/login.png"));//设置按钮图标
btn2->setIcon(QIcon(":/photo/cancel.png"));//设置按钮图标
connect(this->btn1,&QPushButton::clicked,this,&Widget::btn1_slot);
connect(this->btn2,SIGNAL(clicked()),this,SLOT(close()));
}
void Widget::btn1_slot()
{
QString userName = dit1->text();
QString password = dit2->text();
if(userName=="admin"&&password=="123456")
{
qDebug() << "登陆成功";
emit jump();//发送跳转信号
this->close();//关闭界面
}
else
{
qDebug() << "登录失败";
dit1->clear();//清空行编辑器dit1中的内容
dit2->clear();//清空行编辑器dit2中的内容
}
}
Widget::~Widget()
{
}
跳转界面的头文件:
#ifndef SECOND_H
#define SECOND_H
#include <QWidget>
namespace Ui {
class Second;
}
class Second : public QWidget
{
Q_OBJECT
public:
explicit Second(QWidget *parent = nullptr);
~Second();
private:
Ui::Second *ui;
public slots:
void jump_slots();//定义一个接收跳转信号的槽
};
#endif // SECOND_H
跳转界面的实现函数
#include "second.h"
#include "ui_second.h"
Second::Second(QWidget *parent) :
QWidget(parent),
ui(new Ui::Second)
{
ui->setupUi(this);
}
Second::~Second()
{
delete ui;
}
void Second::jump_slots()
{
this->show(); //显示Second中的组件
}
主函数:
#include "widget.h"
#include "second.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Widget w;//实例化Widget类对象,取名w
w.show();//调用w中的show函数,显示w中的所有组件
Second s;//实例化Second类对象,取名s
QObject::connect(&w,&Widget::jump,&s,&Second::jump_slots);
//将w中的jump信号函数连接到s中的jump_slots槽函数中
return a.exec();//阻塞等待
}
运行结果:
当账号密码输入错误时:
当账号密码输入正确(账号为admin,密码为123456)时:
出现的Form界面为切换界面
信号与槽机制实例代码:
头文件:
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include<QPushButton>
#include<QDebug>
#include<QTextToSpeech>
QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE
class Widget : public QWidget
{
Q_OBJECT //信号与槽的元对象
signals:
void my_signal(); //声明一个自定义信号函数,发给别人
public slots:
void my_slots(); //声明一个自定义槽函数,接收别人发来的
public:
Widget(QWidget *parent = nullptr);
~Widget();
private slots:
void on_btn1_clicked();
void on_btn6_clicked();
private:
Ui::Widget *ui;
//自定义一个按钮
QPushButton *btn3;
//定义一个播报员指针
QTextToSpeech *speecher;
};
#endif // WIDGET_H
实现函数:
#include "widget.h"
#include "ui_widget.h"
void Widget::my_slots()
{
static int num=0;
if(num%2==0)
{
ui->btn1->setEnabled(false);//设置不可用状态
}
else
ui->btn1->setEnabled(true);//设置可用状态
num++;
}
void fun()
{
//qDebug() << "我是路过的";
}
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
//给播报员实例化空间
speecher = new QTextToSpeech(this);
//给btn3实例化空间
this->btn3=new QPushButton("按钮3",this);
this->btn3->move(ui->btn1->x(),ui->btn1->y()+50);
this->btn3->resize(ui->btn1->size());
//使用qt4版本的连接,将按钮3发射的pressed信号与按钮1的槽进行连接
connect(btn3,SIGNAL(pressed()),ui->btn1,SLOT(hide()));//按下按钮3关闭按钮1
//参数1:信号的发射者,按钮3的指针
//参数2:要发射的信号,是在按钮所在类中拥有的信号函数,需要使用SIGNAL宏函数进行转换
//参数3:信号的接受者,ui界面上的按钮1
//参数4:处理信号的槽函数,是信号接受者所在类中拥有的槽函数
//注意:该连接方式是不友好的链接,原因:即使宏函数中写错,编译器不报错,但没有现象
//使用qt5版本的链接,将ui上面的btn4按钮发射的clicked信号,与当前界面的自定义的槽函数连接
connect(ui->btn4,&QPushButton::clicked,this,&Widget::my_slots);
//友好的链接
//将ui界面上的按钮5,发送clicked信号,信号连接外部函数或lambda表达式
connect(ui->btn5,&QPushButton::clicked,fun);
//将ui界面上的按钮5发射的clicked信号连接到lambda表达式中
connect(ui->btn5,&QPushButton::clicked,[&](){
//语音播报内容
speecher->say(ui->btn1->text());
});
//将当前界面的my_signal信号连接到自定义的槽函数(当前为lambda表达式)中
connect(this,&Widget::my_signal,[&](){
speecher->say("成功断开按钮3的链接");
});
}
Widget::~Widget()
{
delete ui;
}
//该函数就是按钮2的click信号对应的槽函数
void Widget::on_btn1_clicked()
{
static int num=0;
if(num==20)
{
ui->btn1->close();
}
if(num%3==0)
{
ui->btn1->setStyleSheet("background-color:red;");//按钮变成红色
}
else if(num%3==1)
{
ui->btn1->setStyleSheet("background-color:green;");//按钮变成绿色
}
else
{
ui->btn1->setStyleSheet("background-color:yellow;");//按钮变成黄色
}
num++;
}
void Widget::on_btn6_clicked()
{
disconnect(btn3,SIGNAL(pressed()),ui->btn1,SLOT(hide()));//断开btn3的链接
//发射自定义的信号(不是在按钮6中的信号,是在Widget中的信号)
emit my_signal();
}
主函数:
#include "widget.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Widget w;
w.show();
return a.exec();
}
xmind:
面试题:
1.多态,虚函数,纯虚函数
多态是类的三大属性之一,分为静态多态和动态多态,静态多态是函数重载,动态多态又称动态绑定,在运行时去确定对象的类型和正确选择需要调用的函数,一般用于解决基类指针或引用派生类对象调用类中的重写的函数时出现的问题。多态意为一种形式多种状态,是父类指针或者引用,指向或初始化子类的对象,调用子类对父类重写的函数,进而展开子类的功能。
虚函数是函数前加上virtual,虚函数满足继承,父类中该函数时虚函数,继承到子类中,依然是虚函数,如果子类再被继承,“孙类还是虚函数”。
当类中有虚函数或者继承了虚函数时,类中自动添加一个虚指针,虚指针指向一个虚函数列表,列表中寻访指向虚函数的指针,实际上是一个函数指针数组。虚指针是一个指向函数指针数组的指针。
纯虚函数是当父类中虚函数被子类用来重写,但没有真正意义的时候,把父类中的虚函数写成纯虚函数,有纯虚函数的类是一个抽象类,只能被继承,无法实例化一个具体的对象。每个抽象类中至少有一个纯虚函数。当子类继承了父类的两个纯虚函数但只重写了一个纯虚函数是,就还是一个抽象类,无法实例化一个对象。
2.引用作为函数参数有哪些特点:
1.引用必须在函数定义时声明,且不能为NULL,必须引用一块已经存在的内存空间。
2通过引用传参可以避免复制大量数据,提高程序的执行效率。
3.通过引用传递参数,可以在函数内部对实参进行修改,从而改变原始值,不用返回值。
4.引用参数可以让函数接收不同类型的参数。
5.引用和目标占用同一块空间,在作为参数传递时,不会开辟新的空间,没有值传递和地址传递的区别