QT
#include "mainwindow.h"
#include "ui_mainwindow.h"
#
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
setWindowTitle("Restaurant");
resize(600,400);
//setFixedSize(1200,1500);
ui->setupUi(this);
QPushButton *btn1 = new QPushButton;
btn1->setParent(this);
btn1->setText("login");
btn1->setFixedSize(60,60);
btn1->move(0,40);
}
MainWindow::~MainWindow()
{
delete ui;
}
按钮 指定了父类之后不用自己删掉,会被放到表里被释放掉
//点击窗口触发行为
//槽函数
//参数:发送者(按钮) 信号(函数地址) 接收者(窗口) 槽函数
connect(btn1,&QPushButton::clicked,this,&MainWindow::close);
自定义出发信号类和函数
老师类.h
#include <QObject>
class Teacher : public QObject
{
Q_OBJECT
public:
explicit Teacher(QObject *parent = nullptr);
signals:
// 自定义信号 写道siginals下,可以有参数,可以重载
void hungry();// 返回值是void, 只需要声明,不需要实现
public slots:
};
学生类.h
#include <QObject>
class Student : public QObject
{
Q_OBJECT
public:
explicit Student(QObject *parent = nullptr);
signals:
public slots:
// 学生类需要对老师饿了的信号做出响应
// 返回值void,需要声明,也需要实现
// 可以有参数,可以发生重载
void treat();
};
学生类.cpp
#include "student.h"
#include <QDebug>
Student::Student(QObject *parent) : QObject(parent){}
void Student::treat(){
qDebug() << "treat the teacher";
}
mainWindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
this->te = new Teacher(this);
this->st = new Student(this);
//连接老师和学生的信号
connect(te,&Teacher::hungry,st,&Student::treat);
// 调用下课函数,触发信号
classisOver();
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::classisOver(){
// 下课函数,触发老师饿了的信号
emit te->hungry();
}
参数重载的情况
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
this->te = new Teacher(this);
this->st = new Student(this);
//连接老师和学生的信号
//connect(te,&Teacher::hungry,st,&Student::treat);
// 定义函数指针,指向有参的函数
void (Teacher:: *tesignal)(QString) = &Teacher::hungry;
void (Student:: *stuslot)(QString) = &Student::treat;
connect(te,tesignal,st,stuslot);
// 调用下课函数,触发信号
classisOver();
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::classisOver(){
// 下课函数,触发老师饿了的信号
emit te->hungry("icecream");
}
将QString转为Char *
打印的时候QString会自带引号,需要进行转化
void Student::treat(QString foodName){
//先转QByteArray(.toUtf8()),再转char*(.data())
qDebug()<<"treat the teacher "<<foodName.toUtf8().data();
}
按钮触发函数
\ //点击一个下课按钮出发下课
QPushButton *btn = new QPushButton("overclass",this);
btn->resize(50,50);
btn->move(100,100);
connect(btn,&QPushButton::clicked,this,&MainWindow::classisOver);
按钮连接到触发函数上,触发函数触发信号,老师发出饿了的信号,启动老师和学生之间的连接,触发学生招待的行为
信号连接信号,不通过函数触发。
//信号连接信号
void (Student:: *stuslot2)(void) = &Student::treat;
void (Teacher:: *tesignal2)(void) = &Teacher::hungry;
connect(btn,&QPushButton::clicked,te,tesignal2);
connect(te,tesignal2,st,stuslot2);
一个信号可以连接多个槽函数
多个信号可以连接同一个槽函数
信号和槽函数的参数必须一一对应
信号的参数可以多于槽函数的参数数量
断开信号
//断开信号
disconnect(btn,&QPushButton::clicked,te,tesignal2);
lambda表达式
[](){}();
[=](){btn->settext("Hello")}(); //值传递方式,可以用lambda所在作用域范围内所有可见的局部变量
[&](){btn->settext("Hello")}(); //引用传递方式
[btn](){btn->settext("Hello")}();//只允许看到btn
int m;
connect(btn,&QPushButton::clicked,this,[m]() mutable {m=100+10;qDebug()<<m;});
//如果想修改按值传递进来的拷贝就需要加上mutable,但是这样也不会修改到本体
int ret = []()->int{return 1000}(); //设置返回值类型
//点击按钮关闭窗口
QPushButton *btn2 = new QPushButton;
btn2->setParent(this);
btn2->setText("Close");
connect(btn2,&QPushButton::clicked,this,[this](){this->close();});
QMainWindow
Menu Bar
Tool Bar Area
Dock Widget Area : 可拖动的栏
Central Widget
Status Bar
菜单栏和工具栏设置
//设置菜单栏
QMenuBar *mbar = menuBar();
setMenuBar(mbar);
QMenu *sign = mbar->addMenu("sign");
QMenu *mag = mbar->addMenu("manage");
//创建菜单项
QAction *signin = sign->addAction("signin");
sign->addAction("signup");
QAction *rep = mag->addAction("reception");
mag->addSeparator();
QAction *bak = mag->addAction("backstage");
//设置工具栏
QToolBar * toolbar = new QToolBar(this);
addToolBar(toolbar);
/*设置工具栏项目
toolbar->addAction(signin);
toolbar->addSeparator();
toolbar->addAction(bak);*/
QPushButton *btn1 = new QPushButton("signin");
toolbar->addWidget(btn1);
状态栏设置
//创建状态栏
QStatusBar *stbar = statusBar();
setStatusBar(stbar);
//添加标签控件
QLabel *label1 = new QLabel("Restaurant management system",this);
stbar->addWidget(label1);
浮动窗口和中心部件设置
//创建浮动窗口
QDockWidget *dw = new QDockWidget("flow",this);
addDockWidget(Qt::BottomDockWidgetArea,dw);
//设置中心部件.
QTextEdit * edit = new QTextEdit(this);
setCentralWidget(edit);
添加资源
//ui->actiond_2->setIcon(QIcon("C:\\Users\\vr2019\\Pictures\\3.jpg"));
//添加QT资源到项目,需要先把图片目录复制到工程下
//然后右键项目, 添加新文件,选择模板QT下的QT resource file,获得qrc文件
//进入qrc文件需要右键添加资源
//首先要添加前缀比如装备、首饰做区分
//然后编译一下,文件就放进去了
//添加qt资源图片":加前缀名和文件名"
设置背景样式表和自适应
QWidget#centralWidget{border-image:url(:/images/00.jpg);background-size:100% 100%;}
模态对话框和非模态对话框
//点击登录按钮 弹出一个对话框
connect(ui->action11,&QAction::triggered,this,[=](){
// 弹出对话框#include "QDialog"
// 对话框分类:
// 模态对话框:创建后不可以操作其他窗口
QDialog dig(this);
dig.resize(200,100);
dig.exec(); //相当于阻塞
// 非模态对话框:创建后,可以操作其它窗口
// 因为之后还可以创建其他窗口,所以需要放在堆上
QDialog *dlg= new QDialog(this);
dlg->resize(200,100);
dlg->setAttribute(Qt::WA_DeleteOnClose);// 防止内存泄漏
dlg->show();
});
标准对话框
系统内置了一系列对话框
QColorDialog:选择颜色
QFileDialog:选择文件或者目录
QFontDialog:选择字体
QInputDialog:允许用户输入一个值并返回
QMessageBox:模态对话框,用于显示信息,询问问题等
QPageSetupDialog:为打印机提供纸张相关的选项
QPrintDialog:打印机配置
QPrintPreviewDialog:打印预览
QProgressDialog:显示操作过程
自定义消息框QMessageBox
//点击登录按钮 弹出消息对话框
connect(ui->action11,&QAction::triggered,this,[=](){
//自定义消息对话框
//错误对话框
QMessageBox::critical(this,"critital","错误");
//信息对话框
QMessageBox::information(this,"info","信息");
//警告对话框
QMessageBox::warning(this,"warn","警告");
//question对话框,参数:父,窗口名,内容,选项,默认设置的选项
QMessageBox::StandardButton resl = QMessageBox::question(this,"ques","提问",QMessageBox::Save|QMessageBox::Cancel,QMessageBox::Cancel);
//如何得知用户点了save
if(resl == QMessageBox::Save){
qDebug()<<"执行保存操作";
}
});
颜色对话框
//打开颜色对话框,并设置默认值和透明度
QColor color = QColorDialog::getColor(QColor(255,0,0));
qDebug()<<"r= "<<color.red();
qDebug()<<"g= "<<color.green();
qDebug()<<"b= "<<color.blue();
文件对话框
//打开文件对话框
//返回值:文件路径 参数:父类,窗口标题,默认打开路径,过滤文档(只看得到txt文件)
QString str = QFileDialog::getSaveFileName(this,"打开文件","C:\\Users\\vr2019\\Desktop","(*.txt)");
qDebug()<<str;
字体设置对话框
//字体设置对话框
//参数:bool值,默认字体和字号设置,返回值:选择的字号和字体
bool flag;
QFont font = QFontDialog::getFont(&flag,QFont("Arial",36));
qDebug()<<"font:"<<font.family().toUtf8().data();
qDebug()<<"fontsize:"<<font.pointSize();
触发新窗口
https://blog.csdn.net/m0_37143327/article/details/80265820
页面布局(登录界面设置)
把组件移动到水平分布的框里即可水平对齐
更推荐移动Containers的widget框内,再进行水平或垂直对齐
控制间距用Spacers,可以设置其大小来改变间距,条件(布局)
布局过的窗口会很大,可以通过sizePolicy来缩小空白间隔 Fixed
固定大小:设置最大和最小值一样
密码输入设为暗纹:label属性设置echoMode改为Password
控件
PushButton 添加资源图片用icon图标
toolbutton:主要是添加图片用,文字和图片一起显示 :lButtonStyle, 选中效果:autoraise
RadioButton:单选按钮设置:把radiobutton拖到groupbox里,默认值设置
//默认值设置,选中一个默认的radiobutton
ui->name->setchecked(true);
监听选项
connect(ui->name,&QRadioButtion::clicked,[=](){操作});
CheckBox:多选按钮
ui->name->setchecked(true);
//2是选中,0是未选中。1是半选,需要选中tristate属性才可以有半选
connect(ui->name,&QRadioButtion::stateChanged,[=](int state){操作});
ListView: 文本框
QListWidgetItem *item = new QListWidgetItem("the first line");
ui->listWidget->addItem(item);
item->setTextAlignment(Qt::AlignCenter); //设置水平居中
// QStringList
QStringList list;
list << "the second line" <<"the thrid line"; //连续输入
ui->listWidget->addItems(list);
TreeWidget:目录树
// 设置水平标签头
ui->treeWidget->setHeaderLabels(QStringList()<<"Hero"<<"HeroIntro");
QTreeWidgetItem *stritem = new QTreeWidgetItem(QStringList()<<"Strength");
QTreeWidgetItem *stritem1 = new QTreeWidgetItem(QStringList()<<"Quick");
QTreeWidgetItem *stritem2 = new QTreeWidgetItem(QStringList()<<"Smart");
//添加顶层结点
ui->treeWidget->addTopLevelItem(stritem);
ui->treeWidget->addTopLevelItem(stritem1);
ui->treeWidget->addTopLevelItem(stritem2);
//追加子节点
QStringList hero1;
hero1 << "cai wen ji" <<"help partners restore health";
QTreeWidgetItem *l1 = new QTreeWidgetItem(hero1);
stritem->addChild(l1);
TableWidget :表
//设置列数和行数
ui->tableWidget->setColumnCount(3);
ui->tableWidget->setRowCount(5);
//设置水平表头
ui->tableWidget->setHorizontalHeaderLabels(QStringList()<<"Name"<<"Gender"<<"Age");
//在表中加入内容
QStringList nameList;
nameList << "apple"<<"banana" << "pear";
for(int i =0;i<3;i++){
ui->tableWidget->setItem(0,i,new QTableWidgetItem(nameList[i]));
}
其他控件
ScrollArea :滚动区域,东西拖进来排列之后可以滚动
ToolBox:类似于QQ中联系人,朋友,家人,黑名单等分类方式
TabWidget:类似于浏览器的标签页
StackedWidget:可以切页。设计中可以按箭头切换,但是在运行中需要定义按钮和信号槽来切换页面
ui->stackedWidget->setCurrentIndex(2); // 设置默认值
connect(ui->btn_scrollArea,&QPushButton::clicked,[=](){
ui->stackedWidget->setCurrentIndex(0);
});
connect(ui->btn_ToolBox,&QPushButton::clicked,[=](){
ui->stackedWidget->setCurrentIndex(1);
});
ComboBox:下拉框
ui->comboBix->addItem("AWM");
ui->comboBix->addItem("m416");
ui->comboBix->addItem("98k");
connect(ui->btn_select,&QPushButton::clicked,[=](){
ui->comboBox->setCurrentIndex(2); //点一下按钮设为默认值
});
QLable:文本框,可用于图片显示,以及动图显示
//利用QLabel显示图片,
ui->qlable->setPixmap(":/image/butterfly.png");
//利用QLabel显示动图
QMovie *movie = new QMovie(":/img/imh.gif");
ui->qlable->setMovie(movie);
movie->start();
ProgressBar:进度条
自定义控件
自己进行封装操作:
添加新文件,Qt设计师界面类,选择模板Widget空窗口。 进行设计。设计完之后在主窗口界面上,放一个Widget,右键提升为这个自定义类,点击全局包含和提升,widget变为自定义的控件
例子
//SpinBox移动 QSlider跟着移动
void(QSpinBox:: * spSignal)(int) = &QspinBox::valuechanged;
connect(ui->spinBox,spSignal,ui->slider,&Qslider::setValue);
connect(ui->slider,&Qslider::valuechanged,ui->spinBox,&QpinBox::setValue);
QT事件
鼠标事件
QEnterEvent鼠标进入捕获的
//自定义控件类,在头文件上写
void enterEvent(QEvent *event);
void leaveEvent(QEvent *event);
//在源文件上写
void Mylabel::enterEvent(QEvent *event) //重载鼠标事件
{
qDebug() <<"鼠标进入了";
}
void Mylabel::leaveEvent(QEvent *event)
{
qDebug() <<"鼠标离开了";
}
//在主界面上放一个QLable,右键提升为自定义控件就可以捕捉到事件
//设置QFrame看到框的边界、
//鼠标事件
void enterEvent(QEvent *event);
void leaveEvetn(QEvent *);
void mousePressEvent(QMouseEvent *ev){
QString str = QString("鼠标按下了,x=%1,y=%2").arg(ev->x()).arg(ev->y());
qDebug()<<str; //坐标是基于框的
QString str = QString("鼠标按下了,x=%1,y=%2").arg(ev->x()).arg(ev->y());
qDebug()<<str; //坐标是基于框的,获取全局的ev->globalx()
if(ev->button()==Qt::LeftButton){ //鼠标左键按下
qDebug()<<"鼠标左键释放了";
}
}
void mouseReleaseEvent(QMouseEvent *ev){
}
void mouseMoveEvent(QMouseEvent *ev){
//ev->buttons()
if(ev->buttons() & Qt::LeftButton ){区分移动的情况}
}
//在类中设置setMousetracking(true);进行鼠标追踪为真,只要一移动就可以捕获情况
定时器事件(用第二种方法做)
//在类中重写定时器事件
void timerEvent(QTimerEvent *ev){
if(ev->timerId()==id1){
static int num = 1;
ui->label1->setText(QString::number(num++));
}
if(ev->timerId()==id2){
static int num = 10;
ui->label1->setText(QString::number(num++));
}
}
//在Wdiget中定时器事件,参数:间隔(毫秒单位),
int id1 = startTimer(1000);
int id2 = startTimer(2000);
//如果写了两个怎么区分是用哪个定时器调用的
//第二种方法
QTimer * timer = new QTimer(this);
timer->start(500);
connect(timer,&QTimer::timeout,[=](){
static int num=1;
ui->label->setText(QString::numebr(num++);)
});
//如果两个定时器就new俩,最好用第二种定时器的方法
//点击暂停按钮,停止定时器
connnect(ui->btn,&QPushButton::clicked,[=](){
timer->stop();
});
通过事件分发器拦截事件()
主要说明event分发事件的功能,不建议用来做拦截操作
bool myLabel::event(QEvent *e)
{
//如果是鼠标按下,在event事件分发中做拦截操作
if(e->type()==QEvent::MouseButtonPress){
QString str= QString("巴拉巴拉");
qDebug()<<str;
return true;//代表该类自己处理鼠标按下事件,不向下分发,
//也就是myLabel::MouseButtonPress()函数不会被触发
}
//其他事件, 交给父类处理
return QLable:event(e);
}
事件过滤器
通过事件过滤器,可以在程序分发到event事件之前在做一次高级拦截
使用步骤:
- 给控件安装事件过滤器
- 重写eventfilter事件
封装:
release目录下有:.exe + 保证qt目录下有:windeployqt
新建目录,放入exe文件,运行windeployqt bvala.exe