###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.hUI是窗体外的指针,要手动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版本,博主实验中没发现下划线