MainWindow常见组成:
菜单栏
//菜单栏只能最多有一个
//菜单栏创建
QMenuBar *bar = menuBar();
//将菜单栏放到窗口中
setMenuBar(bar);
//创建菜单
QMenu * fileMenu = bar->addMenu("文件");
QMenu * editMenu = bar->addMenu("编辑");
//创建菜单项
QAction *newAction = fileMenu ->addAction("新建");
//添加分隔符
fileMenu ->addSeparator();
QAction *openAction = fileMenu ->addAction("打开");
工具栏
//工具栏 可以有多个
QToolBar * toolbar = new QToolBar(this);
addToolBar(Qt::LeftToolBarArea,toolbar);
//后期设置 只允许左右停靠
toolbar->setAllowedAreas(Qt::LeftToolBarArea | Qt::RightToolBarArea);
//设置浮动
toolbar -> setFloatable(false);
//设置移动(总开关) 所有的移动都不允许
toolbar ->setMovable(false);
//设置内容
toolbar->addAction(newAction);
//添加分割线
toolbar->addSeparator();
toolbar->addAction(openAction);
//工具栏中添加按钮
QPushButton * btn = new QPushButton;
btn->setText("哈哈哈哈");
toolbar->addWidget(btn);
状态栏
//状态栏 最多有一个
QStatusBar * stBar = statusBar();
//设置到窗口中
setStatusBar(stBar);
//放标签控件
QLabel * label = new QLabel("提示信息",this);
stBar->addWidget(label);
QLabel * label2 = new QLabel("右侧提示信息",this);
stBar->addPermanentWidget(label2);
铆接部件 (浮动窗口)
//铆接部件 (浮动窗口)
QDockWidget * dockWidget = new QDockWidget("浮动",this);
addDockWidget(Qt::BottomDockWidgetArea,dockWidget);
//设置后期停靠区域 只允许上下
dockWidget ->setAllowedAreas(Qt::TopDockWidgetArea | Qt::BottomDockWidgetArea);
核心部件
以QTextEdit为例:
//设置核心部件 只能有一个
QTextEdit * edit = new QTextEdit(this);
setCentralWidget(edit);
资源文件添加
1、将图片文件拷贝到项目位置下
2、右键项目—添加新文件—Qt—Qt resource File —给资源文件起名
3、res 生成 res
4、open in editor 编辑资源
5、添加前缀-- 添加文件
6、使用":+前缀名+文件名"
//绝对路径不实用
//ui->actionNew->setIcon(QIcon("C:/Users/Perfect/Desktop/QT从入门到实战完整版资料/day2资料/Doc/Image/Luffy"));
//使用添加Qt资源 ": +前缀名 + 文件名"
ui->actionNew->setIcon(QIcon(":/Image/Luffy.png"));
ui->actionOpen->setIcon(QIcon(":/Image/LuffyQ.png"));
模态对话框和非模态对话框
模态对话框:
connect(ui->actionNew,&QAction::triggered,this,[=](){
//模态 对话框(不可以对其他窗口进行操作)
//模态创建
QDialog dlg(this);
dlg.resize(200,100);
dlg.exec();
qDebug() <<"模块对话框弹出了";
});
非模态对话框:
connect(ui->actionNew,&QAction::triggered,this,[=](){
//非模态对话框(可以对其他窗口进行操作)
//非模态对话框 要创建到堆上 才不会 直接消失
QDialog *dlg2 = new QDialog(this);
dlg2->resize(200,100);
dlg2->show();
dlg2->setAttribute(Qt::WA_DeleteOnClose); //55号属性 防止内存泄漏
qDebug() <<"非模块对话框弹出了";
});
标准对话框
所谓标准对话框,是 Qt 内置的一系列对话框,用于简化开发。事实上,有很多对话框都是通用的,比如打开文件、设置颜色、打印设置等。这些对话框在所有程序中几乎相同,因此没有必要在每一个程序中都自己实现这么一个对话框。
Qt 的内置对话框大致分为以下几类:
QColorDialog: 选择颜色;
QFileDialog: 选择文件或者目录;
QFontDialog: 选择字体;
QInputDialog: 允许用户输入一个值,并将其值返回;
QMessageBox: 模态对话框,用于显示信息、询问问题等;
QPageSetupDialog: 为打印机提供纸张相关的选项;
QPrintDialog: 打印机配置;
QPrintPreviewDialog:打印预览;
QProgressDialog: 显示操作过程。
颜色对话框:
QColor color = QColorDialog::getColor(QColor(255,0,0));
qDebug()<<"r = "<<color.red()<<" g = "<<color.green()<<" b = "<<color.blue();
字体对话框:
//字体对话框
bool flag;
QFont font = QFontDialog::getFont(&flag,QFont("微软雅黑",36));
qDebug()<<"字体:"<<font.family().toUtf8().data()<<" 字号:"<<font.pointSize()<<" 是否加粗:"<<font.bold()
<<"是否倾斜:"<<font.italic();
消息对话框
错误对话框:
QMessageBox::critical(this,"Critical","错误!");
信息对话框:
QMessageBox::information(this,"info","信息!");
提问对话框:
//参数1 父亲 参数2 标题名称 参数3 提示内容 参数4 按键类型 参数5 默认关联回车的按键
if(QMessageBox::Save == QMessageBox::question(this,"ques","提问",QMessageBox::Save | QMessageBox::Cancel,QMessageBox::Cancel))
{
qDebug() << "选择的是保存!";
}else{
qDebug() << "选择的是取消!";
}
警告对话框:
QMessageBox::warning(this,"warnning","警告!");
文件对话框
//文件对话框
//参数1 父亲 参数2 标题 参数3 默认打开路径 参数4 过滤文件格式
QString str = QFileDialog::getOpenFileName(this,"打开文件","C:\\Users\\Perfect\\Desktop","(*.txt)");
qDebug() <<str; //返回值 是选取的路径
界面布局
实现登陆窗口
1、利用布局方式给窗口进行美化
2、选取widget进行布局:水平布局、垂直布局、栅格布局
3、给用户名、密码、登陆、退出按钮进行布局
4、默认窗口和控件之间有9间隙,可以调整layoutLeftMargin
5、利用弹簧进行布局
6、sizePolicy可以设置水平垂直策略
按钮组
1、QPushButton 常用按钮
2、QToolButton 工具按钮 用于显示图片 如想显示文字,修改风格toolButtonStyle,凸起风格autoRaise
3、radioButton 单选按钮,设置默认 ui->rBtnMan->setChecked(true);
4、checkbox多选按钮 监听状态 2是选中 1半选中 0未选
QListWidge控件
1、利用ListWidget写诗
QListWidgetItem * item = new QListWidgetItem("锄禾日当午");
//将一行诗放到listWidget空间中
ui->listWidget->addItem(item);
item->setTextAlignment(Qt::AlignHCenter);
2、利用addItems一次性添加
//QStringList QList<QString> 直接全放入进去
QStringList list;
list <<"锄禾日当午"<<"汗滴禾下土"<<"谁知盘中餐"<<"粒粒皆辛苦";
ui->listWidget->addItems(list);
QTreeWidget控件
树控件的使用 eg:
//设置水平头
ui->treeWidget->setHeaderLabels(QStringList()<<"英雄"<<"英雄介绍");
//创建根节点
QTreeWidgetItem * liItem = new QTreeWidgetItem(QStringList()<<"力量");
QTreeWidgetItem * minItem = new QTreeWidgetItem(QStringList()<<"敏捷");
QTreeWidgetItem * zhiItem = new QTreeWidgetItem(QStringList()<<"智力");
//加载顶层的节点 添加根节点到树控件上
ui->treeWidget->addTopLevelItem(liItem);
ui->treeWidget->addTopLevelItem(minItem);
ui->treeWidget->addTopLevelItem(zhiItem);
//创建子节点
QStringList heroL1;
heroL1 << "刚被猪"<<"前排坦克,能在吸收伤害的同时造成可观的范围输出";
QTreeWidgetItem * l1 = new QTreeWidgetItem(heroL1);
//添加子节点
liItem->addChild(l1);
QTableWidget控件
//实现tablewidget控件
//设置列数
ui->tableWidget->setColumnCount(3);
//设置水平表头
ui->tableWidget->setHorizontalHeaderLabels(QStringList()<<"姓名"<<"性别"<<"年龄");
//设置行数
ui->tableWidget->setRowCount(5);
//设置正文
//ui->tableWidget->setItem(0,0,new QTableWidgetItem("亚瑟"));
QStringList nameList;
nameList<<"亚瑟"<<"赵云"<<"张飞"<<"关羽"<<"花木兰";
QList<QString> sexList;
sexList<<"男"<<"男"<<"男"<<"男"<<"女";
for(int i =0; i<5; i++)
{
int col = 0;
ui->tableWidget->setItem(i,col++,new QTableWidgetItem(nameList[i]));
ui->tableWidget->setItem(i,col++,new QTableWidgetItem(sexList.at(i)));
ui->tableWidget->setItem(i,col++,new QTableWidgetItem(QString::number((i+18))));
}
其它控件
1、stackWidget 栈控件
//栈空间使用
//设置默认页数
ui->stackedWidget->setCurrentIndex(1);
//scrollArea按钮
connect(ui->btn_scrollArea,&QPushButton::clicked,[=](){
ui->stackedWidget->setCurrentIndex(0);
});
//toolbox按钮
connect(ui->btn_ToolBox,&QPushButton::clicked,[=](){
ui->stackedWidget->setCurrentIndex(1);
});
//Tab按钮
connect(ui->btn_TabWidget,&QPushButton::clicked,[=](){
ui->stackedWidget->setCurrentIndex(2);
});
2、下拉框
//下拉框
ui->comboBox->addItem("奔驰");
ui->comboBox->addItem("宝马");
ui->comboBox->addItem("拖拉机");
//选中
connect(ui->btn_select,&QPushButton::clicked,[=](){
ui->comboBox->setCurrentIndex(2);
});
3、QLabel显示图片
//利用QLabel显示图片
ui->lbl_Image->setPixmap(QPixmap(":/Image/butterfly.png"));
//利用QLabel显示gif动图
QMovie *movie = new QMovie(":/Image/mario.gif");
ui->lbl_movie->setMovie(movie);
//播放动图
movie->start();
自定义控件
1、添加新文件 – QT–设计师界面类 (.h .cpp .ui)
2、.ui 中 设计QSpinBox 和 QSlider两个控件 水平布局
3、Widget中使用自定义控件 拖拽一个Widget,右键–提升为–SmallWidget(设计师界面类名)
4、实现功能,改变数字,滑动条跟着移动,信号槽监听
5、提供getNum 和 setNum对外接口
SmallWidget.h中:
public:
//设置数字
void setNum(int num);
//获取数字
int getNum();
SmallWidget.cpp中:
#include "smallwidget.h"
#include "ui_smallwidget.h"
SmallWidget::SmallWidget(QWidget *parent) :
QWidget(parent),
ui(new Ui::SmallWidget)
{
ui->setupUi(this);
//QSpinBox移动,QSlider跟着移动
void(QSpinBox:: *spSignal)(int) = &QSpinBox::valueChanged;
connect(ui->spinBox,spSignal,ui->horizontalSlider,&QSlider::setValue);
//QSlider滑动 QSpinBox数字跟着改变
connect(ui->horizontalSlider,&QSlider::valueChanged,ui->spinBox,&QSpinBox::setValue);
}
SmallWidget::~SmallWidget()
{
delete ui;
}
void SmallWidget::setNum(int num)
{
ui->spinBox->setValue(num);
}
//获取数字
int SmallWidget::getNum()
{
return ui->spinBox->value();
}
widget.cpp中:
#include "widget.h"
#include "ui_widget.h"
#include <QPushButton>
#include <QDebug>
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
//点击获取 当前控件的值
connect(ui->btn_get,&QPushButton::clicked,[=](){
qDebug() << ui->widget->getNum();
});
//设置到一半
connect(ui->btn_set,&QPushButton::clicked,[=](){
ui->widget->setNum(50);
});
}
Widget::~Widget()
{
delete ui;
}
鼠标事件
myLabel.h:
#ifndef MYLABEL_H
#define MYLABEL_H
#include <QLabel>
class MyLabel : public QLabel
{
Q_OBJECT
public:
explicit MyLabel(QWidget *parent = nullptr);
//鼠标进入事件
void enterEvent(QEvent *event);
//鼠标离开事件
void leaveEvent(QEvent *event);
//鼠标按下
void mousePressEvent(QMouseEvent *ev);
//鼠标释放
void mouseReleaseEvent(QMouseEvent *ev);
//鼠标移动
void mouseMoveEvent(QMouseEvent *ev);
signals:
};
#endif // MYLABEL_H
myLabel.cpp:
#include "mylabel.h"
#include <QDebug>
#include <QMouseEvent>
MyLabel::MyLabel(QWidget *parent) : QLabel(parent)
{
//设置鼠标追踪
setMouseTracking(true);
}
//鼠标进入事件
void MyLabel::enterEvent(QEvent *event)
{
qDebug()<<"鼠标进入了";
}
//鼠标离开事件
void MyLabel::leaveEvent(QEvent *event)
{
qDebug()<<"鼠标离开了";
}
//鼠标按下
void MyLabel::mousePressEvent(QMouseEvent *ev)
{
//鼠标左键
// if(ev->button() == Qt::LeftButton)
// {
QString str = QString("鼠标按下了 x = %1 y = %2 globalX = %3 globalX = %4").arg(ev->x()).arg(ev->y()).arg(ev->globalX()).arg(ev->globalY());
qDebug()<<str;
// }
}
//鼠标释放
void MyLabel::mouseReleaseEvent(QMouseEvent *ev)
{
// if(ev->button() == Qt::LeftButton)
// {
QString str = QString("鼠标释放了 x = %1 y = %2 globalX = %3 globalX = %4").arg(ev->x()).arg(ev->y()).arg(ev->globalX()).arg(ev->globalY());
qDebug()<<str;
// }
}
//鼠标移动
void MyLabel::mouseMoveEvent(QMouseEvent *ev)
{
// if(ev->buttons() & Qt::LeftButton)
// {
QString str = QString("鼠标移动了 x = %1 y = %2 globalX = %3 globalX = %4").arg(ev->x()).arg(ev->y()).arg(ev->globalX()).arg(ev->globalY());
qDebug()<<str;
// }
}
定时器1 - 不推荐
1、利用事件 void timerEvent(QTimerEvent * ev)
widget.cpp中:
//重写定时器的事件
void Widget::timerEvent(QTimerEvent *ev)
{
if(ev->timerId() == id1)
{
//label_2 每隔1秒 +1
static int num = 1;
ui->label_2 -> setText(QString::number(num++));
}
if(ev->timerId() == id2)
{
//label_3 每隔2秒 +1
static int num2 = 1;
ui->label_3 -> setText(QString::number(num2++));
}
}
2、启动定时器 startTimer(1000)
id1 = startTimer(1000); //参数1 间隔(ms)
id2 = startTimer(2000); //参数1 间隔(ms)
3、利用TimerEvent的返回值 是定时器的唯一标识, 可以和ev->timerID做比较
定时器2 - 推荐
1、利用定时器类 QTimer
2、创建定时器对象 QTimer * timer = new QTimer(this);
3、启动定时器 timer->start();
4、每隔一定毫秒,发送信号,timeout() 进行监听
5、暂停 timer->stop();
//定时器的第二种方式 推荐
QTimer * timer = new QTimer(this);
//启动定时器
timer->start(500); //半秒一次
connect(timer,&QTimer::timeout,[=](){
static int num = 1;
ui->label_4->setText(QString::number(num++));
});
//点击暂停按钮 实现停止定时器
connect(ui->pushButton,&QPushButton::clicked,[=](){
timer->stop();
});
event事件分发器
1、用途:用于事件的分发
2、可以做拦截操作,但不建议
bool MyLabel::event(QEvent *e)
{
//如果是鼠标按下,在event事件分发中做拦截操作
if(e->type() == QEvent::MouseButtonPress)
{
//类型转换 从QEvent-》QMouseEvent
QMouseEvent * ev = static_cast<QMouseEvent *>(e);
QString str = QString("Event函数中,鼠标按下了 x = %1 y = %2 globalX = %3 globalX = %4").arg(ev->x()).arg(ev->y()).arg(ev->globalX()).arg(ev->globalY());
qDebug()<<str;
return true; //true代表用户自己处理这个事件,不向下分发
}
//其它事件 交给父类处理 默认处理
return QLabel ::event(e);
}
3、bool event(QEvent * event);
4、如果返回值是true 代表用户处理这个事件,不向下分发了
5、e->type() ==鼠标按下
if(e->type() == QEvent::MouseButtonPress)
事件过滤器
1、在程序将时间分发到事件分发器前,可以利用过滤器做拦截
2、步骤:
①给控件安装事件过滤器
//给label 安装事件过滤器
//步骤1 安装事件过滤器
ui->label->installEventFilter(this);
②重写eventFilter函数
//步骤2 重写eventfilter事件
bool Widget::eventFilter(QObject *obj, QEvent *e)
{
if(obj == ui->label)
{
if(e->type() == QEvent::MouseButtonPress)
{
//类型转换 从QEvent-》QMouseEvent
QMouseEvent * ev = static_cast<QMouseEvent *>(e);
QString str = QString("事件过滤器中,鼠标按下了 x = %1 y = %2 globalX = %3 globalX = %4").arg(ev->x()).arg(ev->y()).arg(ev->globalX()).arg(ev->globalY());
qDebug()<<str;
return true; //true代表用户自己处理这个事件,不向下分发
}
}
//其他默认处理
return QWidget::eventFilter(obj,e);
}
绘图事件
1、绘图事件 void paintEvent(QPaintEvent *)
2、声明一个画家对象
//实例化一个画家对象 this指定的是绘图的设备
QPainter painter(this);
3、设置画笔 QPen 设置宽度、风格
//设置画笔
QPen pen(QColor(255,0,0));
//设置画笔宽度
pen.setWidth(3);
//设置画笔样式
pen.setStyle(Qt::DotLine);
painter.setPen(pen);
4、设置画刷 QBrush
//设置画刷
QBrush brush(Qt::cyan);
//设置画刷风格
brush.setStyle(Qt::Dense7Pattern);
//让画家使用画刷
painter.setBrush(brush);
5、画线、圆、矩形、文字
//画线
painter.drawLine(QPoint(0,0),QPoint(100,100));
//画圆
painter.drawEllipse(QPoint(100,100),50,50); // rx ry 分别为50 画的是圆 不相等-椭圆
//画矩形
painter.drawRect(QRect(20,20,50,50));
//画文字
painter.drawText(QRect(10,200,100,50),"好好学习,天天向上");
绘图高级设置
1、抗锯齿,效率低
QPainter painter(this);
painter.drawEllipse(QPoint(100,50),50,50);
//设置抗锯齿的能力 效率较低
painter.setRenderHint(QPainter::Antialiasing);
painter.drawEllipse(QPoint(200,50),50,50);
2、对画家移动、保存状态
QPainter painter(this);
//画矩形
painter.drawRect(QRect(20,20,50,50));
//移动画家
painter.translate(100,0);
//保存画家状态
painter.save();
painter.drawRect(QRect(20,20,50,50));
painter.translate(100,0);
//还原画家保存的状态
painter.restore();
painter.drawRect(QRect(20,20,50,50));
手动调用绘图事件
1、如果手动调用绘图事件,利用update
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
//点击移动按钮 移动图片
connect(ui->pushButton,&QPushButton::clicked,[=](){
posX += 20;
//如果要手动调用绘图事件,用update()更新
update();
});
}
2、利用 画家画图片
QPainter painter(this);
//如果超出屏幕 从0开始
if(posX > this->width())
{
posX = 0;
}
painter.drawPixmap(posX,0,QPixmap(":/Image/Luffy.png"));
绘图设备
1、QPixmap
//pixmap绘图设备 专门为平台做了显示的优化
QPixmap pix(300,300);
//填充颜色
pix.fill(Qt::white);
//声明画家
QPainter painter(&pix);
painter.setPen(QPen(Qt::green));
painter.drawEllipse(QPoint(150,150),100,100);
//保存
pix.save("F:\\pix.png");
2、QImage 可以对像素进行修改
//QImage 绘图设备 可以对像素进行访问
QImage img(300,300,QImage::Format_RGB32);
img.fill(Qt::white);
QPainter painter(&img);
painter.setPen(QPen(Qt::blue));
painter.drawEllipse(QPoint(150,150),100,100);
//保存
img.save("E:\\img.png");
对像素进行修改(重写绘图事件):
//绘图事件
void Widget::paintEvent(QPaintEvent *)
{
QPainter painter(this);
//利用QImage对像素进行修改
QImage img;
img.load(":/Image/Luffy.png");
//修改像素点
for(int i = 50;i<100;i++)
{
for(int j = 50; j < 100; j ++)
{
QRgb value = qRgb(255,0,0);
img.setPixel(i,j,value);
}
}
painter.drawImage(0,0,img);
}
3、QPicture 可以记录和重现绘图指令
记录:
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
QPicture pic;
QPainter painter;
painter.begin(&pic);//开始往pic上画
painter.setPen(QPen(Qt::cyan));
painter.drawEllipse(QPoint(150,150),100,100);
painter.end(); //结束画画
//保存到磁盘
pic.save("E:\\pic.zt"); //文件记录的画图的过程
}
重现:
//绘图事件
void Widget::paintEvent(QPaintEvent *)
{
//重现QPicture的绘图指令
QPainter painter;
QPicture pic;
pic.load("E:\\pic.zt");
painter.drawPicture(0,0,pic);
}