#include "mainwindow.h"#include //包含一个应用程序类的头文件//argc 命令行变量的数量,argv命令行变量的数组
int main(int argc, char *argv[])
{QApplication a(argc, argv); //有且仅有一个MainWindow w;//窗口对象,默认不会显示,必须调用show方法显示窗口w.show();return a.exec();
}
QT += core gui //Qt包含的模块//版本4以上,加入了widgets模块
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets CONFIG += c++11# The following define makes your compiler emit warnings if you use
# any Qt feature that has been marked deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS# You can also make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0//源文件
SOURCES += \main.cpp \mainwindow.cpp//头文件
HEADERS += \mainwindow.hFORMS += \mainwindow.ui# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target
#ifndef MAINWINDOW_H
#define MAINWINDOW_H#include QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACEclass MainWindow : public QMainWindow
{Q_OBJECT //允许类中使用信号和槽机制public:MainWindow(QWidget *parent = nullptr); //构造函数~MainWindow(); //析构函数private:Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
//QPushButton类
//头文件
#include
#include "mainwindow.h"
#include "ui_mainwindow.h"
#includeMainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{ui->setupUi(this);//创建一个按钮QPushButton *btn=new QPushButton;//让btn依赖在mainwindow窗口中btn->setParent(this);//显示文本,按钮的名字btn->setText("第一个按钮");//创建第二个文本,按照控件的大小创建窗口QPushButton *btn2=new QPushButton("第二个按钮",this); //移动按钮位置,不移动的话,按钮2会覆盖住按钮1btn2->move(100,100);
}MainWindow::~MainWindow()
{delete ui;
}
resize(600,400);
setWindowTitle("xxx窗口名字");
setFixedSize(600,400);
只要指定了父亲,他父亲析构的时候,会把这个孩子也析构掉。
左上角为(0,0)点,x以右为正方向,y以下为正方向。
1.1、connect( 信号的发送者,发送的具体信号,信号的接受者,信号的处理(槽) )
1.2、信号槽的优点:松散耦合,(信号发送端和接收端,本身没有关联,通过connect连接,将2者联系起来)
//connect( 信号的发送者,发送的具体信号,信号的接受者,信号的处理(槽) )//实现按钮关闭界面
connect(btn,&QPushButton::clicked,this,&MainWindow::close);
1.3、Signals
1.4、槽函数(slots)
情景:
老师说:饿了。
学生响应说:请客吃饭。
解析:
老师是信号发送方,学生是信号接收方。
信号:
槽:
注意、调用下课函数,必须先连接,然后再执行触发信号
2.1、Teacher.h
#ifndef TEACHER_H
#define TEACHER_H#include class Teacher : public QObject
{Q_OBJECT
public:explicit Teacher(QObject *parent = nullptr);signals://自定义信号 写到signals下//返回值是void,只需要声明,不需要实现//可以有参数,可以重载void hungry();//实现重载void hungry(QString foodName);
};#endif // TEACHER_H
2.2、Student.h
#ifndef STUDENT_H
#define STUDENT_H#include class Student : public QObject
{Q_OBJECT
public:explicit Student(QObject *parent = nullptr);//槽函数,返回值也是void,//需要声明也需要实现//可以有参数,可以发生重载void treat();//重载版本void treat(QString foodName);signals:};#endif // STUDENT_H
2.3、Student.cpp
#include "student.h"
#include
Student::Student(QObject *parent) : QObject(parent)
{}
void Student::treat()
{qDebug()<<"请老师吃饭";
}
void Student::treat(QString foodName)
{//输出效果// 请老师吃"鱼香肉丝"//想要把""去掉,需要QString->char*qDebug()<<"请老师吃"<
2.4、MainWindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H#include
#include "Teacher"
#include "Student"QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACEclass MainWindow : public QMainWindow
{Q_OBJECTpublic:MainWindow(QWidget *parent = nullptr);~MainWindow();private:Ui::MainWindow *ui;//添加2个变量Teacher *zt; Student *st;//实现触发信号void classIsOver();};
#endif // MAINWINDOW_H
2.5、MainWindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{ui->setupUi(this);//创建一个老师对象this->zt=new Teacher(this);//创建一个学生对象this->st=new Student(this);//建立连接connect(zt,&Teacher::hungry,st,&Student::treat);//调用下课函数,必须先连接,然后再执行触发信号classIsOver();//调用带参,这是是因为有重载函数,出现了二义性,所以需要指明要调用哪一个void(Teacher:: *teacherSignal)(QString)=&Teacher::hungry;void(Student:: *studentSlot)(QString)=&Student::treat;connect(zt,teacherSignal,st,studentSlot);classIsOver();
}MainWindow::~MainWindow()
{delete ui;
}void MainWindow::classIsOver()
{
//emit是触发信号的关键字。//emit zt->hungry();//重载版本emit zt->hungry("鱼香肉丝");
}
MainWindow.cpp 其余页面不变
#include "mainwindow.h"
#include "ui_mainwindow.h"MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{ui->setupUi(this);//创建一个老师对象this->zt=new Teacher(this);//创建一个学生对象this->st=new Student(this);void(Teacher:: *teacherSignal)(QString)=&Teacher::hungry;void(Student:: *studentSlot)(QString)=&Student::treat;connect(zt,teacherSignal,st,studentSlot);//点击 一个下课的按钮,再触发下课 QPushButton *btn=new QPushButton("下课",this);this->resize(600,400);connect(btn,&QPushButton::clicked,this,&MainWindow::classIsOver);}MainWindow::~MainWindow()
{delete ui;
}void MainWindow::classIsOver()
{
//emit是触发信号的关键字。//重载版本emit zt->hungry("鱼香肉丝");
}
MainWindow.cpp , 其余页面不变
#include "mainwindow.h"
#include "ui_mainwindow.h"MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{ui->setupUi(this);//创建一个老师对象this->zt=new Teacher(this);//创建一个学生对象this->st=new Student(this);void(Teacher:: *teacherSignal2)(void)=&Teacher::hungry;void(Student:: *studentSlot2)(void)=&Student::treat;connect(zt,teacherSignal2,st,studentSlot2);//点击 一个下课的按钮,再触发下课 QPushButton *btn=new QPushButton("下课",this);this->resize(600,400);//信号连接信号 connect(btn,&QPushButton::clicked,zt,teacherSignal2);}MainWindow::~MainWindow()
{delete ui;
}void MainWindow::classIsOver()
{
//emit是触发信号的关键字。//重载版本emit zt->hungry("鱼香肉丝");
}
void(Teacher:: *teacherSignal2)(void)=&Teacher::hungry;void(Student:: *studentSlot2)(void)=&Student::treat;connect(zt,teacherSignal2,st,studentSlot2);//断开信号disconnect(zt,teacherSignal2,st,studentSlot2);
//声明//不可修改传入的值
[]()->返回类型{ //函数体
};
//可以修改传入的值
[]()mutable{};//调用
[]()->返回类型{ //函数体
}();
以上是一个Lambda表达式的声明
[]必须有,它表示这是一个Lambda表达式
QPushButton *btn=new QPushButton("下课",this);connect(btn,&QPushButton::clicked,this,[](){qDebug()<<"测试Lambda表达式"});
QPushButton *btn=new QPushButton("下课",this);connect(btn,&QPushButton::clicked,this,[](){this->close();});
2.1、创建菜单栏
菜单栏最多只能有一个
MainWindow.cpp
#include
//创建菜单栏
QMenuBar *bar=menuBar();
//将菜单栏放入窗口中
setMenuBar(bar);//创建菜单
QMenu * fileMenu=bar->addMenu("文件");
QMenu * editMenu=bar->addMenu("编辑");//添加一个菜单项
fileMenu->addAction("新建");
fileMenu->addAction("打开");//添加分隔线
fileMenu->addSeparator();
#include
QToolBar *toolBar=new QToolBar(this);
addToolBar(toolBar); //默认在上面//后期只允许左右停靠
toolBar->setAllowedAreas(Qt::LeftToolBarArea | Qt::RightToolBarArea)
//设置浮动toolBar->setFloatable(false);
//设置移动
toolBar->setMoveable(false);//工具栏设置内容
QAction *openAction=fileName->addAction("打开");
toolBar->addAction(openAction);//工具栏中添加控件
QPushButton *btn=new QPushButton("aa",this);
toolBar->addWidget(btn);
#include
QStatusBar *stBar=statusBar();
//设置到窗口中
setStatusBar(stBar);//放标签控件
QLable *lable=new QLable("提示信息",this);
stBar->addWidget(lable);
QDockWidget *dock=new QDockWidget("浮动",this);
addDockWidget(Qt::BottomDockWidgetArea,dock);//设置后期停靠区域,具体操作与工具栏操作一样#include
//设置中心部件
QTextEdit *edit=new QTextEdit(this);
setCentralWidget(edit);
前缀类似于包名
再点击添加文件
MainWindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#includeMainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{ui->setupUi(this);//先使用拖文件的方式创建//使用添加Qt资源,":+前缀名+文件名"ui->actionNew->setIcon(QIcon(":+前缀名+文件名"));
}MainWindow::~MainWindow()
{delete ui;
}
引入头文件
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include
#include
MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{ui->setupUi(this);//点击新建按钮,弹出一个对话框 connect(ui->actionNew,&QAction::triggered,[=](){//模态创建QDialog dlg(this);dlg.resize(200,100);dlg.exec(); })}MainWindow::~MainWindow()
{delete ui;
}
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include
#include
MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{ui->setupUi(this);//点击新建按钮,弹出一个对话框 connect(ui->actionNew,&QAction::triggered,[=](){//非模态创建QDialog *dlg=new QDialog(this);dlg->resize(200,100);dlg->show();//关闭后就释放,防止内存泄露dlg->setAttribute(Qt::WA_DeleteOnClose);})}MainWindow::~MainWindow()
{delete ui;
}
引入头文件
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include
#include
#include
MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{ui->setupUi(this);//点击新建按钮,弹出一个对话框 connect(ui->actionNew,&QAction::triggered,[=](){//消息对话框//错误对话框//critical(父亲,标题,错误提示)QMessageBox::critical(this,"critical","错误");//信息对话框QMessageBox::information(this,"inf","信息"); //问题对话题(例如显示保存还是退出,默认显示,yes no)QMessageBox::question(this,"ques","信息"); //问题对话框,修改成save,cancelQMessageBox::question(this,"ques","信息" Qt::QMessageBox::Save|Qt::QMessageBox::Cancel); if(QMessageBox::Save== QMessageBox::question(this,"ques","信息" Qt::QMessageBox::Save|Qt::QMessageBox::Cancel)) {qDebug()<<"选择的是保存";} //警告对话框
QMessageBox::warning(this,"warning","警告"); })
}MainWindow::~MainWindow()
{delete ui;
}
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include
#include
#include
MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{ui->setupUi(this);//点击新建按钮,弹出一个对话框 connect(ui->actionNew,&QAction::triggered,[=](){//颜色对话框,(类似于打开拾色器)//返回值为RGBQClolor color= QColorDialog::getColor(QColor(255,0,0));//文件对话框QFileDialog::getOpenFileName(this,"打开文件","默认打开的位置");//文件对话框,过滤一下文件,只显示.txt文件//返回值是选取的路径//参数1 父亲,参数2 标题 ,参数3,默认打开路径,参数4 过滤文件类型QString str= QFileDialog::getOpenFileName(this,"打开文件","默认打开的位置","*.txt");//字体对话框bool flag;QFont font= QFontDialog::getFont(&flag,QFont("黑体",16));})
}MainWindow::~MainWindow()
{delete ui;
}
1、步骤:
1、在UI布局内拖拽实现
2、拖拽Lable,在上面写上用户名
3、放到用户名旁边,实现输入
4、再拖拽这个,实现登录和退出。
5、实现水平布局
效果:
6、实现垂直布局
添加弹簧,使这些按钮可以随页面大小改变而改变。2个按钮之间的弹簧,设置成固定的,防止窗口改变时,2个按钮距离也会改变。
设置成这样:
7、实现用户,密码,输入框,4者对齐
然后把用户名,密码,输入框都拖进去。
然后再加上弹簧
默认窗口和控件之间有9个空隙,可以调整layoutLeftMargin
可以在控件上添加图片
这样图片和文字都可以在控件上显示了。
想要变透明,可以在QToolButton选中autoRaise
可以用group Box,把同一组的放在一起。
可以设置默认选择状态
ui->那个控件名称->setChecked(true);
connect(ui->cBox,&QCheckBox::stateChanged,[=](int state){
//点击一下,打印2,不选择打印0
qDebug()<
//先设置列数
ui->tableWidget->setColumnCount(具体数字);//设置水平表头
ui->tableWidget->setHorizontalHeaderLable(QStringList()<<"姓名"<<"性别"<<"年龄");//设置行数
ui->tableWidget->setRowCount(具体数字);
//设置具体内容
ui->tableWidget->setItem(0,0,new QTalbeWidgetItem("具体名字"));
QStringList nameList;
nameList<<"具体名字1"<<"具体名字2"<<"具体名字3";for(int i=0;i<3;i++)
{ui->tableWidget->setItem(i,0,new QTalbeWidgetItem(nameList[i])); //int 转 QStringQString::number(i+18);
}
带有滑动的功能
类似于QQ里面的那个分组效果。
网页效果。
如果觉得页数不够,可以插入新的页
ui->comboBox->addItem("具体东西");
设置多行文本,类似于记事本。支持倾斜,加粗。
显示标签,也可显示图片。
//利用QLabel显示图片
ui->comboBox->setPixmap(QPixmap(":+文件源"));//显示动态图
#include
QMovie* movie=new QMovie(":+动图路径");
ui->comboBox->setMovie(movie);
//播放动图
movie->start();
1、
2、点击完成后,就可以进行设置控件了。
3、先看自己设计的控件,叫什么类型
这里就是自己设计的控件类型。
4、然后在原来的ui设计窗口
选择和自己设计的类型相同的控件,然后右键,选择提升为
5、在这里填写你自定义控件的类名称
6、写完后,选择全局包含,再点击添加,然后再点击提升,就完成了创建。
7、2个部件进行关联
在自定义控件.cpp里面
//spinBox,horizontalSlider 是控件的名称
//控件名称,可以在ui设计界面,点击控件,右下角有属性栏,在里面可以查找名称。//QSpinBox移动,QSlider跟着移动
void(QSpinBox:: *spSignal)(int)=&QSpinBox::valueChanged;connect(ui->spinBox,spSignal,ui->horizontalSlider,QSlider::setValue);//QSlider移动,QSpinBox跟着移动
horizontalSliderconnect(ui->horizontalSlider,&QSlider::valueChanged,ui->spinBox,QSpinBox::setValue);
在进行提升操作之后,才能实现以下方法
xxx.h
//鼠标进入事件
void enterEvent(QEvent *event);
void leaveEvent(QEvent*);
//鼠标摁下
void mousePressEvent(QMouseEvent *ev);
//鼠标释放
void mouseReleaseEvent(QMouseEvent *ev);
//鼠标移动
void mouseMoveEvent(QMouseEvent *ev);
xxx.cpp
void xxx:: enterEvent(QEvent *event)
{qDebug()<<"鼠标进去了";
}
void xxx::leaveEvent(QEvent*)
{qDebug()<<"鼠标出去了";
}
//鼠标摁下
void xxx::mousePressEvent(QMouseEvent *ev)
{//捕捉摁下信息ev->x; //x坐标ev->y; //y坐标QString str=QString("x=1%,y=2%").arg(ev->x()).arg(ev->y())qDebug()<globalx; //基于屏幕ev->globaly;//鼠标左键if(ev->button==Qt::LeftButton);//右键if(ev->button==Qt::RightButton);}
//鼠标释放
void xxx::mouseReleaseEvent(QMouseEvent *ev)
{}
//鼠标移动
void xxx::mouseMoveEvent(QMouseEvent *ev)
{//这是个连续状态,使用buttons//摁住左键移动if(ev->button & Qt::Leftbutton);}
单个计时器
mainWidget.h
//重写定时器
void timerEvent(QTimerEvent * ev);
mainWidget.cpp
void mainWidget::timerEvent(QTimerEvent *ev)
{//实现从1开始加static int num=1;ui->控件名字->setText(QString::number(num++));}
//启动定时器
MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{ui->setupUi(this);startTimer(1000);//参数1 间隔时间,单位是 毫秒}
2.1.2、有多个定时器时,使用定时器id,来分别操纵各个定时器
mainWidget.h
//重写定时器
void timerEvent(QTimerEvent * ev);
int id1,id2;
mainWidget.cpp
//启动定时器
MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{ui->setupUi(this);int id1=startTimer(1000);//参数1 间隔时间,单位是 毫秒int id2=startTimer(2000);
}void mainWidget::timerEvent(QTimerEvent *ev)
{//每隔1s加一if(ev->timerId()==id1){//实现从1开始加static int num=1;ui->控件名字->setText(QString::number(num++)); }//每隔2s加一if(ev->timerId()==id2){//实现从1开始加static int num2=1;ui->控件名字->setText(QString::number(num2++)); }}
1、使用计时器类
mainWidget.cpp
//启动定时器
MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{ui->setupUi(this);QTimer* timer=new QTimer(this);//每隔0.5s,参数可以更改timer->start(500);connect(timer,&QTimer::timeout,[=](){static int num2=1;ui->控件名字->setText(QString::number(num2++)); })}
2、点击暂停按钮,实现计时器暂停
mainWidget.cpp
//启动定时器
MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{ui->setupUi(this);QTimer* timer=new QTimer(this);//每隔0.5s,参数可以更改timer->start(500);connect(timer,&QTimer::timeout,[=](){static int num2=1;ui->控件名字->setText(QString::number(num2++)); })//btn为按钮的位置
connect(ui->btn,&QPushButton::clicked,[=](){timer->stop();
})}
以鼠标按下为例:
mainWidget.h
bool event(QEvent *ev);
mainWidget.cpp
bool XXX::event(QEvent *ev)
{//如果鼠标摁下,做拦截操作if(ev->type()==QEvent::MouseButtonPress){//具体操作.....return true; //代表用户要处理这个事。不再向下分发}//其他事件交给父类处理,return QWidget::event(ev);
}
可以在事件分发器之前进行拦截
以鼠标按下为例
mainWidget.h
bool eventFilter(QObject* obj,QEvent* e);
mainWidget.cpp
//步骤1、给控件安装事件过滤器ui->控件名字->installEventFilter(this);//步骤2、重写事件过滤器的事件
bool manWidget::eventFilter(QObject* obj,QEvent* e)
{if(obj==ui->控件名){if(e->type()==QEvent::MouseButtonPress){//具体操作return true;}}return QWidget::event(ev);
}
会自动调用这个函数。不需要写调用。
void mainWidget::paintEvent(QPaintEven *)
{//实例化画家对象//在当前窗口绘画QPainter painter(this); //this,指定的是绘图的设备//设置画笔颜色QPen pen(QColor(255,0,0));//设置画笔宽度pen.setWide(2);//设置画笔风格pen.setStyle(Qt::DoLine); //虚线//让画家使用画笔painter.setPen(pen);//设置画刷QBrush brsh(Qt::red);//让画家使用画刷painter.setBrush(brsh);//画一条线painter.drawLine(QPoint(0,0),QPoint(100,100));//画圆painter.drawEllipse(QPoint(0,0),50,50);//画矩形//参数1,左上定点x值,参数2,左上顶点y值,参数3,长,参数4,框painter.drawRect(QRect(20,20,50,50));//画文字painter.drawText(QRect(20,20,50,50),"好好学习");}
void mainWidget::paintEvent(QPaintEven *)
{//实例化画家对象//在当前窗口绘画QPainter painter(this); //this,指定的是绘图的设备painter.drawEllipse(QPoint(0,0),50,50);//设置抗锯齿能力,效率低painter.setRenderHint(QPinter::Antialiasing);painter.drawEllipse(QPoint(60,70),50,50);painter.drawRect(QRect(20,20,50,50));painter.translate(100,0); //让画家移动开始画的位置。//保存画家状态painter.save();//还原画家状态painter.restore();painter.drawRect(QRect(20,20,50,50));//这2个图形不会重合}
先添加好资源文件
void mainWidget::paintEvent(QPaintEven *)
{//实例化画家对象//在当前窗口绘画QPainter painter(this); //this,指定的是绘图的设备//参数1,在左顶点x值,参数2,左顶点y值,从(x,y)绘画图片painter.drawPixmap(20,0,QPixmap(":资源名"));}
MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{ui->setupUi(this);//btn为按钮的位置,点击按钮,移动图片
connect(ui->btn,&QPushButton::clicked,[=](){//前提是定义一个变量,x的值或y的值,每次都变换。Update();
})}
//点击选取文件,弹出文件对话框
connect(ui->btn,&QPushButton::clicked,[=](){QString path=QFileDialog::getOpenFileName(this,"打开文件","默认打开路径")ui->lineEdit->setText(path);//读取内容,放入到textEdit,默认为utf-8QFile file(path); //参数是读取文件路径file.open(QIODevice::ReaddOnly ) ; //设置打开方式QByteArray arry=file.readAll();//将读取的数据,放入textEdit中ui->textEdit->setText(arry);//编码格式类//设置编码格式//QTextCodec* codec=QTextCodec::codecForName("utf-8");// ui->textEdit->setText(codec->toUnicode(arry)); file.close();
})
//点击选取文件,弹出文件对话框
connect(ui->btn,&QPushButton::clicked,[=](){QString path=QFileDialog::getOpenFileName(this,"打开文件","默认打开路径")ui->lineEdit->setText(path);//读取内容,放入到textEdit,默认为utf-8QFile file(path); //参数是读取文件路径file.open(QIODevice::Append ) ; //设置打开方式,追加写file.write("AAAAAAAAAA");file.close();
})
//文件信息类
QFileInf info(path);
qDebug()<<"大小"<
参考文献
B站-最新QT从入门到实战完整版|传智教育–传智教育