###day01回顾
1
//Mywidget.cpp
Mywidget::Mywidget(QWidget*parent):QWidget(parent)
{
}
/*
作用域符:: 构造函数Mywidget(传一个指向父类型的指针){}
:继承 QWidget基类,但是基类也需要传递参数构造它自己
所以使用构造函数初始化列表(以上这种格式)
*/
2
QT内存管理:关闭窗口时自动delete部件
所以创建部件时要创建指针,然后new出来。最后退出时,自动delete才不会出错。
###day02新知识:
简单减法实验:
- 简单减法复习
复习day1知识,做简单减法。
新建窗口部件项目QWidget
头文件中声明指针和自定义槽函数(必须在Q_OBJECT宏定义之后声明):
private:
QPushButton *button1;
QLineEdit *line1;
QLineEdit *line2;
QLineEdit *line3;
QLabel *label;
private slots:
void sub();
void mytest();
.cpp文件中分配内存,初始化
label=new QLabel("-");
button1=new QPushButton("=");
line1=new QLineEdit;
line2=new QLineEdit;
line3=new QLineEdit;
//test->mytest();
QHBoxLayout *layout=new QHBoxLayout();
//QHBoxLayout *layout;
//layout=new QHBoxLayout(this);
//connect(button1,&QPushButton::pressed,this,test);
//connect(button1,&QPushButton::pressed,this,&Mywidget::sub);正确,两个参数类型都是取函数地址
//connect(button1,&QPushButton::pressed,this,SLOT(sub()));错误,槽函数和信号类型必须保持一致
connect(button1,SIGNAL(clicked(bool)),this,SLOT(sub()));
layout->addWidget(line1);
layout->addWidget(label);
layout->addWidget(line2);
layout->addWidget(button1);
layout->addWidget(line3);
setLayout(layout);
实现槽函数:
void Mywidget::sub(){
double a=line1->text().toDouble();
double b=line2->text().toDouble();
double c=a-b;
line3->setText(QString::number(c));
}
void Mywidget::mytest(){
double a=line1->text().toDouble();
double b=line2->text().toDouble();
double c=a-b;
line3->setText(QString::number(c));
}
- 代码实现简易计算器
新建项目,包含ui文件。插入窗口部件…转到槽
void Widget::on_pushButton_clicked()
{
//int aa=(10/5);
//qDebug()<<"test:"<<aa;
double a=ui->lineEdit->text().toDouble();
double b=ui->lineEdit_2->text().toDouble();
double c;
int index=ui->comboBox->currentIndex();
//switch index:
if(index==0)
c=a+b;
else if(index==1)
c=a-b;
else if(index==2)
c=a*b;
else if(index==3)
c=a/b;
ui->lineEdit_3->setText(QString::number(c));
}
第一步,新建Widget项目,不包含ui文件。在头文件中包含#include ,声明指针和槽函数
private slots:
void add();
void sub();
void mul();
void div();
void jisuan();
private:
QLineEdit*lineEdit1;
QComboBox*comboBox;
QLineEdit*lineEdit2;
QPushButton*pushButton;
QLineEdit*lineEdit3;
在.cpp中分配内存,初始化,把部件加载到布局里。
lineEdit1=new QLineEdit;//成员变量,可以访问槽函数
comboBox=new QComboBox;
comboBox->addItem("+");
comboBox->addItem("-");
comboBox->addItem("×");
comboBox->addItem("÷");
lineEdit2=new QLineEdit;
pushButton=new QPushButton("=");
lineEdit3=new QLineEdit;
QHBoxLayout*layout=new QHBoxLayout;
//局部变量,不用访问槽函数
layout->addWidget(lineEdit1);
layout->addWidget(comboBox);
layout->addWidget(lineEdit2);
layout->addWidget(pushButton);
layout->addWidget(lineEdit3);
setLayout(layout);
连接信号与槽
//connect(pushButton,&QPushButton::pressed,this,&Widget::add);//一直是加法
connect(pushButton,&QPushButton::pressed,this,&Widget::jisuan);
实现槽函数
void Widget::add()
{
double a=lineEdit1->text().toDouble();
double b=lineEdit2->text().toDouble();
double c=a+b;
lineEdit3->setText(QString::number(c));
}
void Widget::jisuan()
{
double a=lineEdit1->text().toDouble();
double b=lineEdit2->text().toDouble();
double c;
int index=comboBox->currentIndex();
switch(index){
case 0:
c=a+b;
break;
case 1:
c=a-b;
break;
case 2:
c=a*b;
break;
case 3:
c=a/b;
break;
default:
break;
}
lineEdit3->setText(QString::number(c));
}
void Widget::sub(){}
void Widget::mul(){}
void Widget::div(){}
- UI设计简易计算器
说明:
- widget.ui(界面文件,xml文本)通过uic编译时生成u_widget.h
- UI是窗体外的指针,要手动delete
举例:
class A;//声明
class B {};//定义
继续完善实验
实验内容:
- 仅当lineedit框中有内容,使能find按钮
- checkbox
- 水平对齐,垂直对齐
- 点击close关闭对话框
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fFtKTAih-1597878032174)(https://i.imgur.com/wlCPYk0.jpg)]
方式1. 代码设计
思路分析:
我们需要在头文件中声明一个label(find what),两个checkbox,两个pushbutton(find、close),一个lineedit。自定义槽函数绑定lineedit的信号,实现功能1。
步骤:
新建项目,不包含ui文件,基类为dialog。在dialog.h头文件中包含QtWidgets.h(常用窗体部件模块),在类中声明结构体指针
private slots:
void showtalk();
private:
QLabel * label;
QLineEdit * line1;
QCheckBox *checkbox1;
QCheckBox *checkbox2;
QPushButton *button1;
QPushButton *button2;
在dialog.cpp中,我们给指针分配内存,设置初始化值,并完成布局layout。
label=new QLabel(“find what:”);
line1=new QLineEdit;
checkbox1=new QCheckBox(“match case”);
checkbox2=new QCheckBox(“search backward”);
button1=new QPushButton(“find”);
button2=new QPushButton(“close”);
QHBoxLayout *layout=new QHBoxLayout;//第一层水平布局1
layout->addWidget(label);
layout->addWidget(line1);
QVBoxLayout *layout2=new QVBoxLayout;//第二层垂直布局2
layout2->addLayout(layout);//插入布局1
layout2->addWidget(checkbox1);
layout2->addWidget(checkbox2);
QVBoxLayout *layout3=new QVBoxLayout;//第三层垂直布局3
layout3->addWidget(button1);
layout3->addWidget(button2);
layout3->addStretch();//弹簧,使布局3置顶
QHBoxLayout *layout4=new QHBoxLayout;//第四层水平布局4
layout4->addLayout(layout2);
layout4->addLayout(layout3);
setLayout(layout4);//设置布局4
button1->setEnabled(false);//开始时将find按钮设置为不可见
最后实现两个信号与槽函数绑定
connect(button2,SIGNAL(clicked()),this,SLOT(close()));
connect(line1,SIGNAL(textChanged(QString)),this,SLOT(showtalk()));
检测lineedit的内容,隐藏pushbutton。在槽函数中这样实现
void Dialog::showtalk()
{
button1->setEnabled(!line1->text().isEmpty());
}
方式2. UI设计
新建项目,包含ui文件,双击.ui文件进入设计师模式
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YfEpOZWU-1597878032176)(https://i.imgur.com/mYghlnG.jpg)]
如图插入窗体部件,设置布局,然后转入槽,在槽函数中实现功能
void Dialog::on_lineEdit_textChanged(const QString &arg1)
{
ui->pushButton_2->setEnabled(!arg1.isEmpty());
}
##拓展知识:
参考网友原文https://www.kancloud.cn/kancloud/qt-study-road-2/99449
拓展实验:
1. Lambda表达式–匿名函数
按下按钮,打印“testing!”
新建项目,继承Qwidget,不包含ui文件。头文件中声明指针
private:
QPushButton *button1;
别忘了包含
widget.cpp:
Widget::Widget(QWidget *parent)
: QWidget(parent)
{
button1=new QPushButton("testLambda");
QHBoxLayout *layout=new QHBoxLayout();
//QObject::connect(button1,&QPushButton::pressed,this,[](bool)错误,参数press()和[](bool)不匹配,选择1删除bool
QObject::connect(button1,&QPushButton::pressed,this,[](){
qDebug()<<"testing!";
});
layout->addWidget(button1);
setLayout(layout);
}
2. 信号和槽(Lambda表达式和简单加法)
Qt 5 中,任何成员函数、static 函数、全局函数和 Lambda 表达式(匿名函数)都可以作为槽函数。
widget.h:
private:
QPushButton* mykey;//"="
QLineEdit *line1;//加数
QLineEdit *line2;//加数
QLineEdit *line3;//结果
QLabel *label;//"+"
widget.cpp的构造函数中:
label=new QLabel("+");
mykey=new QPushButton("=");
line1=new QLineEdit;
line2=new QLineEdit;
line3=new QLineEdit;
QHBoxLayout *layout=new QHBoxLayout();
layout->addWidget(line1);
layout->addWidget(label);
layout->addWidget(line2);
layout->addWidget(mykey);
layout->addWidget(line3);
//connect(mykey,&QPushButton::pressed,[]()错误
//error: 'this' was not captured for this lambda function
//改正: []() 改为 [this]()
connect(mykey,&QPushButton::pressed,[this](){
double a=line1->text().toDouble();
double b=line2->text().toDouble();
double c=a+b;
line3->setText(QString::number(c));
});
setLayout(layout);
3. 添加动作,菜单工具状态
实验内容:
做一个主窗口,添加菜单工具状态栏,在菜单栏下添加选项A,在工具栏下也添加选项A。点击该选项进入槽函数,弹出消息提示框。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tEJGeVx6-1597878032178)(https://i.imgur.com/2umziZs.jpg)]
思路分析:
新建一个MainWindow主窗口工程,我们在mainwindow.cpp实现主要功能,故添加头文件
#include<QAction>//动作
#include <QMenuBar>//菜单栏
#include <QMessageBox>//消息提示窗
#include <QStatusBar>//状态栏
#include <QToolBar>//工具栏
-
在mainwindow.h里声明一个动作结构体QAction指针和我们执行动作的函数open。
class MainWindow : public QMainWindow { ... private: void open(); QAction *openAction; ... }
然后,在mainwindow.cpp里
为指针分配内存并实现这个执行动作的函数。
-
我们开始写mainwindow.cpp,创建菜单栏,工具栏,状态栏
//菜单项的名字tr("文件") QMenu *file=menuBar()->addMenu(tr("文件")); //把openAction这个对象添加到菜单栏,在菜单中这个对象显示为选项 file->addAction(openAction); //工具栏名字tr("工具"),在主窗口按右键可以显示 QToolBar *toolBar=addToolBar(tr("工具")); //把openAction这个对象添加到工具栏,在工具栏中这个对象显示为按钮 toolBar->addAction(openAction); //状态栏 statusBar();
-
我们需要一个动作结构体对象来操作,可以在构造时初始化,或者构造出来再分别初始化,区别在于我们调用哪一个构造函数。这次我们选择new一个QAction类并初始化
//构造函数原型 QAction(const QIcon &icon, const QString &text, QObject *parent = nullptr) //例子//关于QIcon需要右键点击工程添加资源文件,此处:/new/prefix1/face是face.png添加到工程文件夹中 openAction=new QAction(QIcon(":/new/prefix1/face"),tr("打开文件"),this);//冒号表示从exe中提取资源 //可以用别名引用face.png。参考(https://www.kancloud.cn/kancloud/qt-study-road-2/99449)
依次填充动作对象里面的属性
//说明快捷键
openAction->setShortcuts(QKeySequence::Open);
//鼠标指向图标时在主窗口下方状态栏显示提示信息
openAction->setStatusTip(tr("点击打开文件"));
动作对象初始化完成,我们需要实现这个对象发出信号,然后主窗口接收,执行槽函数弹出消息窗口处理信号
//将这个QAction的triggered()信号与MainWindow类的open()函数连接起来。
//当用户点击了这个QAction时,会自动触发MainWindow的open()函数。
connect(openAction,&QAction::triggered,this,&MainWindow::open);
-
3.在上述步骤完成了MainWindow::MainWindow(QWidget *parent)
-
QMainWindow(parent)构造函数,接下来实现槽函数void MainWindow::open()
弹出消息提示框QMessageBox::information(this,tr(“提示信息”), tr(“打开了!”));
疑惑:
QAction第二个参数中,文本值前面有一个 &,意味着这将成为一个快捷键。菜单栏中 File 名字的 F 有一个下划线。
但是在QT5.7版本,博主实验中没发现下划线