QT乱七八糟随便记

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

视频学习地址

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章