目录

1、创建第一个Qt程序

2、命名规范以及快捷键

3、QPushBottom的创建

4、对象树

5、Qt中的坐标系

6、信号和槽

6.1 实现点击按钮关闭窗口

6.2 自定义的信号和槽

6.3 自定义的信号和槽发生重载的解决

6.4 信号连接信号

6.5 Qt4版本信号连接

6.5 Lambda表达式

6.6 信号槽的总结

7、QMainWindow

7.1 菜单栏和工具栏

7.2 状态栏、铆接部件、核心部件

8、资源文件的添加

9、模态和非模态对话框创建

10、消息对话框

11、其他对话框

12、登陆窗口布局

13、控件

13.1 按钮组

13.2 QListWidget控件

13.3 QTreeWidget控件

13.4 QTableWidget控件

13.5 其他控件介绍

14、自定义控件

15、Qt的鼠标事件

16、定时器

17、event 事件分发器和事件过滤器

​编辑

18、QPainter

18.1 绘图事件

18.2 绘图高级设置

18.3 手动调用绘图事件

18.4 绘图设备

19、QFile文件读写操作

文件QFile和文件信息读写QFileInfo

20、翻金币项目

***问题总结


1、创建第一个Qt程序

Create Project->Qt Widgets Application(创建一个Qt应用,包含一个基于qt设计师的主窗体)

->Location(不能有空格和中文,可以有下划线),路径选择不能有中文(重要!!!)->Build System(选择qmake,ps:一般的Qt工程你就直接使用qmake就可以了,cmake的强大功能一般人是用不到的 //参考的另一篇博客)->Details(QWidget是QDialog和QMainWindow的父类,Qwidget是空窗口,QMainWindow多了工具栏,QDialog是对话框),选择QWidget作为基类,取消Generate form使用代码编写。->Kits(选择套件)->Summary(finish)团队开发时,添加到版本控制系统(svn,vss,git)

main函数代码

#include "mywidget.h"#include <QApplication>// 包含一个应用程序类的头文件// main程序入口 argc命令行变量的数量 argv命令行变量的数组
int main(int argc, char *argv[])
{QApplication a(argc, argv);// a应用程序对象,在qt中,有且仅有一个MyWidget w;// 创建窗口对象,MyWidget的父类->QWidgetw.show();// 窗口对象 默认不会显示,必须调用show方法显示return a.exec();//让应用程序对象a进入消息循环机制,等待用户点叉叉,使得窗口不会一闪而过,使代码阻塞到这一行
}

2、命名规范以及快捷键

.pro文件不要添加任何东西,除非你知道写的是什么。.pro文件就是工程文件,它是qmake自动生

成的用于生产makefile的配置文件。

QT       += core gui //Qt包含的模块greaterThan(QT_MAJOR_VERSION, 4): QT += widgets//大于4版本以上,包含widget模块CONFIG += c++17# You can make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0
//源文件
SOURCES += \main.cpp \mywidget.cpp
//头文件 自动生成的
HEADERS += \mywidget.h

Qt基本模块

mywidget.h

#ifndef MYWIDGET_H
#define MYWIDGET_H#include <QWidget>//窗口类头文件 QWidgetclass MyWidget : public QWidget
{Q_OBJECT // Q_OBJECT宏,允许类中使用信号和槽的机制public:MyWidget(QWidget *parent = nullptr); // 有参构造函数~MyWidget();
};
#endif // MYWIDGET_H

mywidget.cpp

#include "mywidget.h"// 命名规范
// 类名 首字母大写,单词和单词之间首字母大写
// 函数名 变量名称 首字母小写,单词和单词之间首字母大写// 快捷键
// 注释 ctrl + /
// 运行 ctrl + r
// 编译 ctrl + b
// 字体缩放 ctrl + 鼠标滚轮
// 查找 ctrl + f
// 整行移动 ctrl + shift + ⬆或者⬇
// 帮助文档 F1
// 自动对齐 ctrl + i
// 同名之间的.h和.cpp切换 F4// 帮助文档,左侧的帮助;在Qt5.16\mingw49_32\bin的Qt助手MyWidget::MyWidget(QWidget *parent): QWidget(parent)// 初始化列表
{
}MyWidget::~MyWidget()
{
}

3、QPushBottom的创建

构造函数里创建

#include "mywidget.h"
#include <QPushButton>MyWidget::MyWidget(QWidget *parent): QWidget(parent)// 初始化列表
{// 创建一个按钮QPushButton * btn = new QPushButton;// btn->show();// show以顶层方式弹出窗口控件// 让btn对象 依赖在 MyWdget窗口中btn->setParent(this);// 显示文本btn->setText("first button");// 创建第二个按钮 按照控件的大小创建窗口QPushButton * btn2 = new QPushButton("second button",this);// 重置窗口大小 长x宽resize(600,400);// 移动btn2按钮,设置坐标btn2->move(100,100);// 设置固定窗口大小,用户不能改变串窗口大小setFixedSize(600,400);// 设置窗口标题setWindowTitle("第一个窗口");}MyWidget::~MyWidget()
{
}

4、对象树

父类先构造,子类先析构

在Qt中创建对象的时候会提供一个Parent对象指针。

QObject是以对象树的形式组织起来的。

当你创建一个QObject对象时候,会看到QObject的构造函数接收一个QObject指针作为参数,这个参数就是Parent,也就是父对象指针。

这相当于,在创建QObject对象时,可以提供一个其父对象,我们创建的这个QObject对象会自动添加到其父类对象的children()列表。

当父类对象析构的时候,这个列表中的所有对象也会被析构(注意:这里的父对象并不是继承意义的父类

QWdget是能够在屏幕上显示的一切组件的父类。
QWidget继承自QObject,因此也继承了这种对象树关系。一个孩子自动地成为父组件的一个子组件。因此,它会显示在父组件的坐标系统中,被父组件的边界剪裁。例如,当用户关闭一个对话框的时侯,应用程序将共刑除,那么,我们希望属于这个对话框的按钮、图标等应该一起被迸除。事实就是如此,因为这些都是对话框的子组件。

MyPushButton类的创建

#ifndef MYPUSHBUTTON_H
#define MYPUSHBUTTON_H#include <QPushButton>//继承QPushButton,没有这个选择就先选择继承它的父亲class MyPushButton : public QPushButton
{Q_OBJECT
public:explicit MyPushButton(QWidget *parent = nullptr);~MyPushButton();signals:};#endif // MYPUSHBUTTON_H
#include "mypushbutton.h"
#include <QDebug>//打印输出MyPushButton::MyPushButton(QWidget *parent): QPushButton(parent)//换父亲
{qDebug()<<"我的按钮类构造调用";
}MyPushButton::~MyPushButton()
{qDebug()<<"我的按钮类析构调用";
}

打印先打印的是儿子的析构,但是是后面释放。

#include "mywidget.h"
#include <QPushButton>
#include <mypushbutton.h>
#include <QDebug>//打印输出
MyWidget::MyWidget(QWidget *parent): QWidget(parent)// 初始化列表
{// 创建一个自己的按钮对象MyPushButton *mybtn = new MyPushButton;mybtn->setText("我自己的按钮");mybtn->move(200,0);mybtn->setParent(this);qDebug()<<"MyWidget构造";
}MyWidget::~MyWidget()
{qDebug()<<"MyWidget析构";
}

总结:当创建的对象在堆区时候,如果指定的父亲是QObject派生下来的类或者QObject子类派生下来的类,可以不用管理释放的操作(就是不用deletex),将对象会放入到对象树中。一定程度上简化了内存回收机制

5、Qt中的坐标系

左上角为(0,0),x向右增大,y向下增大

6、信号和槽

6.1 实现点击按钮关闭窗口

connect( 信号的发送者,发送的具体信号,信号的接受者,信号的处理(槽))

信号槽的优点:松散耦合,信号发送端和接受端本身是没有关联的,通过connect连接将两端耦合在一起。

#include "mywidget.h"
#include <QPushButton>
#include <mypushbutton.h>
#include <QDebug>//打印输出
MyWidget::MyWidget(QWidget *parent): QWidget(parent)// 初始化列表
{// 创建一个自己的按钮对象MyPushButton *mybtn = new MyPushButton;mybtn->setText("我自己的按钮");mybtn->move(200,0);mybtn->setParent(this);// 点击我的按钮,关掉窗口// 参数1:信号的发送者,参数2:发送的具体信号(点击)函数的地址;参数3:信号的接受者this窗口,参数4:信号的处理(槽)函数地址connect(mybtn,&MyPushButton::clicked,this,&MyWidget::close);//connect(mybtn,&QPushButton::clicked,this,&QWidget::close);// 用父类的也可以
}MyWidget::~MyWidget()
{
}

6.2 自定义的信号和槽

自定义信号:写到signals下;返回值是void,只需要声明,不需要实现;可以有参数,可以重载。

自定义槽:早期Qt槽函数必须写在public slot下,高级版本可以写道public或者全局下;返回值是void,需要声明,也需要实现;可以有参数,可以重载。

触发自定义信号:emit

#include "widget.h"// Teacher 类 老师类
// Student 类 学生类
// 下课后,老师会触发一个信号,饿了,学生响应信号,请客吃饭Widget::Widget(QWidget *parent): QWidget(parent)
{// 创建老师和学生对象,并且指定父亲,就不用释放this->zt = new Teacher(this);this->st = new Student(this);connect(zt,&Teacher::Hungry,st,&Student::treat);// 调用下课,触发老师饿了,随后学生响应classisover();
}Widget::~Widget()
{
}void Widget::classisover()
{// 下课函数 调用后触发老师饿了信号emit zt->Hungry();
}

6.3 自定义的信号和槽发生重载的解决

1.需要利用函数指针明确指向函数的地址,成员函数指针需要加上作用域

2.QString->char * 先转成QByteArray(.toUtf8())再转char*(),.data的返回值是char *

Widget代码

#include "widget.h"// Teacher 类 老师类
// Student 类 学生类
// 下课后,老师会触发一个信号,饿了,学生响应信号,请客吃饭Widget::Widget(QWidget *parent): QWidget(parent)
{// 创建老师和学生对象,并且指定父亲,就不用释放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();
}Widget::~Widget()
{
}void Widget::classisover()
{// 下课函数 调用后触发老师饿了信号,两个信号emit zt->Hungry();emit zt->Hungry("宫保鸡丁");
}

槽函数重载

#include "student.h"
#include <QDebug>
Student::Student(QObject *parent): QObject{parent}
{}void Student::treat()
{qDebug()<<"请老师吃饭";
}
void Student::treat(QString foodname)// 重载treat
{//打印QString类型有引号,要转成char*就没有引号//qDebug()<<"请老师吃饭,老师要吃:"<<foodname;// QString->char * 先转成QByteArray(.toUtf8())再转char*(),data的返回值是char *qDebug()<<"请老师吃饭,老师要吃:"<<foodname.toUtf8().data();
}

信号重载

void Hungry();
void Hungry(QString foodname);

6.4 信号连接信号

connect(btn,&QPushButton::clicked,zt,teacherSignal);teacherSignal要换成无参形式,否则参数不匹配;

#include "widget.h"
#include <QPushButton>
// Teacher 类 老师类
// Student 类 学生类
// 下课后,老师会触发一个信号,饿了,学生响应信号,请客吃饭Widget::Widget(QWidget *parent): QWidget(parent)
{// 创建老师和学生对象,并且指定父亲,就不用释放this->zt = new Teacher(this);this->st = new Student(this);//点击一个按钮,再下课,再触发老师饿了QPushButton *btn = new QPushButton("下课",this);this->resize(600,400); // 重置窗口大小connect(btn,&QPushButton::clicked,this,&Widget::classisover);//无参信号和槽连接void(Teacher::*teacherSignal)(void) = &Teacher::Hungry;// 成员函数的函数指针void(Student::*studentSlot)(void) = &Student::treat;connect(zt,teacherSignal,st,studentSlot);// 信号连接信号 之间跳过下课,按钮直接使老师饿了connect(btn,&QPushButton::clicked,zt,teacherSignal);// 断开信号//disconnect(zt,teacherSignal,st,studentSlot);
}Widget::~Widget()
{
}void Widget::classisover()
{// 下课函数 调用后触发老师饿了信号,两个信号emit zt->Hungry();emit zt->Hungry("宫保鸡丁");
}

6.5 Qt4版本信号连接

1.信号可以连接信号;

2.一个信号可以连接多个槽函数;

3.多个信号可以连接同一个槽函数;

4.信号和槽函数的参数,必须一一对应;

5.信号的参数个数可以多于槽函数的参数个数,但是类型要一一对应

clicked的参数是bool类型,teacherSignal如果是QString参数就不是一一对应,如果是void参数就是信号的参数比槽函数的参数多,所以不会报错。

6.Qt4:connect(zt,SIGNAL(hungry()),st,SLOT(treat(QString));参数直观,但是不做类型检测,不推荐。

6.5 Lambda表达式

C++11中的Lambda表达式用于定义并创建匿名函数对象,以简化编程工作。

表达式:[函数对象参数](操作符重载函数参数)mutable->返回值(函数体)

① “=”为值传递,“&”为地址传递,a为只对a可见;

② mutable关键字,用于修饰值传递的变量,修改拷贝而不是本体;

③ int ret = [ ]( )->int {return 100;}();使得ret=100;

Widget::Widget(QWidget *parent): QWidget(parent)
{QPushButton *btn = new QPushButton;this->resize(600,400); // 重置窗口大小btn->setText("close");btn->setParent(this);//把按钮安到窗口上//利用lambda表达式实现关闭按钮connect(btn,&QPushButton::clicked,this,[=](){this->close();btn->setText("aaa");});}

6.6 信号槽的总结

任务:设计一个窗口,两个按钮,点击open打开另一个窗口,点击close关闭窗口。

#include "widget.h"
#include "ui_widget.h"
#include <QPushButton>
Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);QPushButton *btn = new QPushButton;btn->setText("open");btn->setParent(this);resize(600,400);QPushButton *btn2 = new QPushButton;btn2->setText("close");btn2->setParent(this);btn2->move(200,200);QWidget *w2=new QWidget;connect(btn,&QPushButton::clicked,w2,&QWidget::show);connect(btn2,&QPushButton::clicked,w2,&QWidget::close);}Widget::~Widget()
{delete ui;
}

任务:设计一个窗口,一个按钮,点击open打开另一个窗口,open变成close,再点击close关闭窗口,close变成open。

#include "widget.h"
#include "ui_widget.h"
#include <QPushButton>
Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);QPushButton *btn = new QPushButton;btn->setText("open");btn->setParent(this);resize(600,400);QWidget *w1 = new QWidget;connect(btn,&QPushButton::clicked,w1,[=](){if(btn->text()=="open"){btn->setText("close");w1->show();}if(btn->text()=="close"){btn->setText("open");w1->close();}});
}Widget::~Widget()
{delete ui;
}

7、QMainWindow

7.1 菜单栏和工具栏

1.菜单栏最多只有一个,工具栏可以有多个

2.QMenu,QToolBar

#include "mainwindow.h"
#include <QMenuBar>
#include <QToolBar>
#include <QPushButton>
MainWindow::MainWindow(QWidget *parent): QMainWindow(parent)
{// 重置窗口大小resize(600,400);// 菜单栏的创建 最多只有一个QMenuBar *bar = menuBar();// 本身在对象树setMenuBar(bar); // 将菜单栏放入窗口中QMenu *fileMenu = bar->addMenu("文件"); // 创建菜单QMenu *editMenu = bar->addMenu("编辑");QAction * newAction = fileMenu->addAction("新建");// 创建菜单项// 添加分割线fileMenu->addSeparator();QAction * newAction1 = fileMenu->addAction("打开");editMenu->addAction("复制");// 工具栏的创建 可以有多个QToolBar *toolBar = new QToolBar(this);addToolBar(Qt::LeftToolBarArea,toolBar);//默认在左边// 只允许左右停靠toolBar->setAllowedAreas(Qt::LeftToolBarArea | Qt::RightToolBarArea);// 设置浮动toolBar->setFloatable(false);// 设置移动,bool值设置是否可以移动,相当于总开关toolBar->setMovable(false);// 设置内容toolBar->addAction(newAction);toolBar->addSeparator();toolBar->addAction(newAction1);// 工具栏添加控件QPushButton* btn = new QPushButton("aa",this);toolBar->addWidget(btn);}MainWindow::~MainWindow()
{
}

7.2 状态栏、铆接部件、核心部件

1.QStatusBar,QDockWidget(浮动窗口),QTextEdit;

    // 状态栏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 *edit = new QTextEdit(this);setCentralWidget(edit);

8、资源文件的添加

1. 将图片文件拷贝到项目位置;

2. 右键项目->添加新文件->Qt->Qt recourse File->给资源文件起名

3. rec生成rec.qrc

4. open in editor打开文件

5. 添加前缀 添加文件,编译

6. 使用“:+前缀名+文件名”

9、模态和非模态对话框创建

1. 模态对话框:不可以对其他窗口进行操作;QDialog dlg(this);dlg.exec();

2. 非模态对话框:可以对其他窗口进行操作;QDialog *dlg2 = new QDialog(this);dlg2->show();

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDialog>
#include <QDebug>
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();//模态方式创建,阻塞功能qDebug()<<"模态对话框弹出了";// 非模态对话框QDialog *dlg2 = new QDialog(this);//存在内存泄漏风险,创建堆区dlg2->resize(200,100);dlg2->show();dlg2->setAttribute(Qt::WA_DeleteOnClose);//设置属性,差掉就释放内存qDebug()<<"非模态对话框弹出了";});
}MainWindow::~MainWindow()
{delete ui;
}

10、消息对话框

QMessageBox 静态成员函数 创建对话框

错误、信息、提问、警告

利用返回值来判断用户的选择

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDialog>
#include <QDebug>
#include <QMessageBox>
MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{ui->setupUi(this);// 点击新建按钮 弹出会话框connect(ui->actionnew,&QAction::triggered,[=](){//消息对话框//QMessageBox::critical(this,"critical","错误");//错误对话框//QMessageBox::information(this,"info","信息");//信息对话框//提问对话框//参数1:父亲,参数2:标题;参数3:提示内容;参数4:按键类型;参数5:默认关联回车按键
//        QMessageBox::question(this,"ques","提问",QMessageBox::Save|QMessageBox::Cancel,QMessageBox::Cancel);
//        if(QMessageBox::Save ==  QMessageBox::question(this,"ques","提问",QMessageBox::Save|QMessageBox::Cancel,QMessageBox::Cancel))
//        {
//            qDebug()<<"选择了保存";
//        }
//        else
//        {
//            qDebug()<<"选择了取消";
//        }//警告对话框QMessageBox::warning(this,"warning","警告");});
}MainWindow::~MainWindow()
{delete ui;
}

11、其他对话框

QColorDialog,QFileDialog,QFontDialog

 // 点击新建按钮 弹出会话框connect(ui->actionnew,&QAction::triggered,[=](){//颜色对话框
//        QColor color = QColorDialog::getColor(QColor(255,0,0));
//        qDebug()<<"r = "<<color.red()<<"g = "<<color.green()<<"b = "<<color.blue();//文件对话框,参数1:父亲 参数2:名字 参数3:路径 参数4:过滤文件格式
//        QString str = QFileDialog::getOpenFileName(this,"打开文件","E:\\BaseFile\\senior\\C++work","(*.doc)");
//        qDebug()<<str;bool flag;QFont font = QFontDialog::getFont(&flag,QFont("华文彩云",32));qDebug()<<font.family();});

12、登陆窗口布局

1. 实现登录窗口;

2. 利用布局方式 给窗口进行美化;

3. 选取widget进行布局,水平布局、垂直布局、栅格布局;

4. 给用户名、密码、登录、退出按钮进行布局;

5. 默认窗口和控件之间有9间隙,可以调整 layoutLeftMargin;

6. 利用弹簧进行布局。

13、控件

13.1 按钮组

1. QPushButton 常用按钮;

2. QToolButton 工具按钮;用于显示图片,如图想显示文字,修改风格;ToolButtonStyle;

3. radioButton 单选按钮,设置默认选择ui->woman->setChecked(true);

4. checkbox 多选按钮,监听状态,2是选中,1是半选,0是未选。

Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);//设置单选按钮,男默认选中ui->woman->setChecked(true);//多选按钮,0表示为选择,2表示选中connect(ui->cBox,&QCheckBox::stateChanged,[=](int state){qDebug()<<state;});
}

13.2 QListWidget控件

QListWidget 列表容器:QListWidgetItem 显示一行内容;

设置居中方式setTextAlignment(),通过查询assitant帮助文档查询参数。

 // 利用listWidget写诗
//    QListWidgetItem *item = new QListWidgetItem("一川烟雨,满城风絮,梅子黄时雨");
//    ui->listWidget->addItem(item);//放到listWidget控件里
//    item->setTextAlignment(Qt::AlignCenter);//水平居中//QStringList QList<QString>QStringList list;list<<"陌上花开"<<"可缓缓归矣";ui->listWidget->addItems(list);

13.3 QTreeWidget控件

1. 设置水平头 setHeaderLabels();

2. 创建根节点  QTreeWidgetItem *item1 = new QTreeWidgetItem(QStringList()<<"力量");

3. 添加根节点到树控件  ui->treeWidget->addTopLevelItem(item1);

4. 添加子节点 item1->addChild(l1);

#include "widget.h"
#include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);// treeWidget// 设置水平头ui->treeWidget->setHeaderLabels(QStringList()<<"英雄"<<"英雄介绍");QTreeWidgetItem *item1 = new QTreeWidgetItem(QStringList()<<"力量");//匿名对象QTreeWidgetItem *item2 = new QTreeWidgetItem(QStringList()<<"敏捷");QTreeWidgetItem *item3 = new QTreeWidgetItem(QStringList()<<"智力");// 加载顶层的节点ui->treeWidget->addTopLevelItem(item1);ui->treeWidget->addTopLevelItem(item2);ui->treeWidget->addTopLevelItem(item3);//追加子节点QStringList heroL1,heroL2,heroL3;heroL1<<"200";heroL2<<"100";heroL3<<"130";QTreeWidgetItem *l1 = new QTreeWidgetItem(heroL1);QTreeWidgetItem *l2 = new QTreeWidgetItem(heroL2);QTreeWidgetItem *l3 = new QTreeWidgetItem(heroL3);item1->addChild(l1);item2->addChild(l2);item3->addChild(l3);
}Widget::~Widget()
{delete ui;
}

13.4 QTableWidget控件

#include "widget.h"
#include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);// 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)));//at越界抛异常//int 转QStringui->tableWidget->setItem(i,col++,new QTableWidgetItem(QString::number(i+18)));}}Widget::~Widget()
{delete ui;
}

13.5 其他控件介绍

1. stackedWidget控件

2. 下拉框控件comboBox

3. QLabel显示图片和gif

#include "widget.h"
#include "ui_widget.h"
#include <QMovie>
Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);// 栈控件使用// 欢迎按钮// 设置默认页面ui->stackedWidget->setCurrentIndex(0);connect(ui->btn_welcome,&QPushButton::clicked,[=](){ui->stackedWidget->setCurrentIndex(0);});// 编辑按钮connect(ui->btn_edit,&QPushButton::clicked,[=](){ui->stackedWidget->setCurrentIndex(1);});// 项目按钮connect(ui->btn_project,&QPushButton::clicked,[=](){ui->stackedWidget->setCurrentIndex(2);});// 下拉框ui->comboBox->addItem("奔驰");ui->comboBox->addItem("宝马");ui->comboBox->addItem("自行车");connect(ui->btn_bike,&QPushButton::clicked,[=](){//ui->comboBox->setCurrentIndex(2);ui->comboBox->setCurrentText("自行车");});// 利用QLabel显示图片和gif动态图片ui->lb1->setPixmap(QPixmap(":/Image/1.jpg"));QMovie *movie = new QMovie(":/Image/m.gif");ui->lb1->setMovie(movie);//嵌入到lblmovie->start();//动起来
}Widget::~Widget()
{delete ui;
}

14、自定义控件

1、添加新文件,Qt->设计师界面类(.cpp .h .ui)

2、.ui中设计 QSpinBox和QSlider两个控件

3、Widget中使用自定义控件,拖拽一个Widget,点击提升为,点击添加,点击提升,将.ui变成一个smallWidget类

4、在smallWidget.cpp实现功能,改变数字,滑动条跟着移动,信号槽监听

5、提供两个按钮,对ui的smallWidget实例对象进行操作

#include "widget.h"
#include "ui_widget.h"
#include <QDebug>
Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);// 点击获取控件当前值connect(ui->btn_set,&QPushButton::clicked,[=](){qDebug()<<ui->widget->getNum();});connect(ui->btn_half,&QPushButton::clicked,[=](){ui->widget->setNum(50);});
}Widget::~Widget()
{delete ui;
}

15、Qt的鼠标事件

1、鼠标进入事件enterEvent

2、鼠标离开事件leaveEvent

3、鼠标移动 mouseMoveEvent

4、鼠标按下 mousePressEvent

5、鼠标释放 mouseReleaseEvent

6、ev->x(),ev->y()

7、ev->button() 可以判断所有按键,Qt::LeftButton,Qt::RightButton

8、ev->buttons() 判断组合按键,判断用 &

9、格式化字符串 QString str = QString(“%1  %2 %3 ...”).arg().arg().arg()...

#include "mylabel.h"
#include <QDebug>
#include <QMouseEvent>
myLabel::myLabel(QWidget *parent): QLabel{parent}
{//设置鼠标追踪状态,默认是falsesetMouseTracking(true);}
void myLabel::enterEvent(QEvent *event)
{qDebug()<<"鼠标进入";
}void myLabel::leaveEvent(QEvent *)
{qDebug()<<"鼠标离开";
}void myLabel::mouseMoveEvent(QMouseEvent *ev)//持续过程
{
//    if(ev->buttons() & Qt::LeftButton)//同真才为真
//    {QString str = QString("鼠标移动了,x = %1 y = %2 globalx = %3 globaly = %4").arg(ev->x()).arg(ev->y()).arg(ev->globalX()).arg(ev->globalY());qDebug()<<str;
//    }}
void myLabel::mousePressEvent(QMouseEvent *ev)//瞬间
{
//    if(ev->button() == Qt::LeftButton)//左键才打印
//    {QString str = QString("鼠标按下了,x = %1 y = %2 globalx = %3 globaly = %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 globaly = %4").arg(ev->x()).arg(ev->y()).arg(ev->globalX()).arg(ev->globalY());qDebug()<<str;
//    }}

16、定时器

1、利用事件void timerEvent(QTimerEvent *e)

2、启动定时器 startTimer(1000)毫秒单位

3、timerEvent的返回值是定时器定时器的唯一标识,可以和 e->timerId 做比较

4、利用定时器类 QTimer

5、先创建定时器对象,启动定时器start(毫秒)

6、每隔一定毫秒,发送信号timeout,进行监听

#include "widget.h"
#include "ui_widget.h"
#include <QTimer>
Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);// 启动定时器 单位是毫秒id1 = startTimer(1000);id2 = startTimer(2000);//定时器第二种方式QTimer *timer = new QTimer(this);//启动定时器timer->start(500);//0.5s进入中断connect(timer,&QTimer::timeout,[=](){static int num = 1;//每0.5s加1;ui->label_4->setText(QString::number(num++));});connect(ui->stop,&QPushButton::clicked,[=](){timer->stop();});
}Widget::~Widget()
{delete ui;
}void Widget::timerEvent(QTimerEvent *e)
{//label_2 每隔1s +1if(e->timerId()==id1){static int num1 = 1;ui->label_2->setText(QString::number(num1++));}//label_3 每隔2s +1if(e->timerId()==id2)//判断定时器{static int num2 = 1;ui->label_3->setText(QString::number(num2++));}}

17、event 事件分发器和事件过滤器

1、用于时间的分发,也可以做拦截(不建议)

2、bool event(QEvent *e)返回值是true代表永华处理这个事件,不向下分发

3、e->type() == 鼠标按下

bool myLabel::event(QEvent *e)
{if(e->type() == QEvent::MouseButtonPress)//鼠标按下,在事件event事件中做拦截操作{QMouseEvent *ev = static_cast<QMouseEvent*>(e);//将e转换为ev类型QString str = QString("event中,,鼠标按下了,x = %1 y = %2 globalx = %3 globaly = %4").arg(ev->x()).arg(ev->y()).arg(ev->globalX()).arg(ev->globalY());qDebug()<<str;return true;//代表用户自己处理事件,不向下分发}//其他事件交给父类处理return QLabel::event(e);
}
---------------------------------------------------------------------------------
bool Widget::eventFilter(QObject *obj,QEvent *e)
{if(obj == ui->label){if(e->type() == QEvent::MouseButtonPress)//鼠标按下,在事件event事件中做拦截操作{QMouseEvent *ev = static_cast<QMouseEvent*>(e);//将e转换为ev类型QString str = QString("事件过滤器中,,鼠标按下了,x = %1 y = %2 globalx = %3 globaly = %4").arg(ev->x()).arg(ev->y()).arg(ev->globalX()).arg(ev->globalY());qDebug()<<str;return true;//代表用户自己处理事件,不向下分发}}// 其他默认处理return QWidget::eventFilter(obj,e);
}

18、QPainter

18.1 绘图事件

1、绘图事件 void paintEvent()

2、声明一个画家对象

void Widget::paintEvent(QPaintEvent *)
{//实例化画家对象 this指定的是绘图设备QPainter painter(this);//设置画笔QPen pen(QColor(255,0,0));//设置画笔宽度pen.setWidth(3);//设置画笔风格pen.setStyle(Qt::DotLine);//让画家使用这个笔painter.setPen(pen);//设置画刷QBrush brush(Qt::cyan);//设置画刷风格brush.setStyle(Qt::Dense7Pattern);//让画家使用画刷painter.setBrush(brush);//划线painter.drawLine(QPoint(0,0),QPoint(100,100));//画圆 椭圆painter.drawEllipse(QPoint(100,100),50,50);
}

18.2 绘图高级设置

1、抗锯齿,效率低

2、对画家进行移动,保存状态,还原状态

void Widget::paintEvent(QPaintEvent *)
{QPainter painter(this);painter.drawEllipse(QPoint(100,50),50,50);//设置抗锯齿能力 效率低painter.setRenderHint(QPainter::Antialiasing);painter.drawEllipse(QPoint(200,50),50,50);//画矩形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));
}

18.3 手动调用绘图事件

如果想手动调用绘图事件,利用update,利用画家画图片painterDrawPixmap

Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);//移动connect(ui->btn_move,&QPushButton::clicked,[=](){//如果要手动调用绘图事件,用update更新update();posx += 20;});
}
void Widget::paintEvent(QPaintEvent *)
{QPainter painter(this);//如果超过屏幕,重新开始if(posx > this->width()){posx = 0;}painter.drawPixmap(posx,0,QPixmap(":/Image_1/10.jpg"));
}

18.4 绘图设备

1. QPixmap QImage QBitmap(黑白)QPicture QWidget

2. QPixmap 对不同平台做了显示优化

3. QImage可以对像素进行访问

4. QPicture可以记录和重现绘图指令

#include "widget.h"
#include "ui_widget.h"
#include <QPixmap>
#include <QPainter>
#include <QImage>
#include <QPicture>
Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);//    //Pixmap绘图设备 专门为平台做了显示的优化
//    QPixmap pix(400,400);
//    QPainter painter(&pix);
//    //填充颜色
//    pix.fill(Qt::white);
//    painter.setPen(QPen(Qt::blue));
//    painter.drawEllipse(QPoint(200,200),100,100);//    //保存到磁盘
//    pix.save("E:\\pix.png");//QImage 绘图设备 可以对像素进行访问
//    QImage img(300,300,QImage::Format_RGB666);
//    img.fill(Qt::white);
//    QPainter painter(&img);
//    painter.setPen(QPen(Qt::blue));
//    painter.drawEllipse(QPoint(200,200),100,100);
//    img.save("E:\\img.png");//QPicture 绘图设备 可以记录和重新绘图指令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 *event)
{//利用QImage对像素点修改
//    QPainter painter(this);
//    QImage img;
//    img.load(":/Image_1/10.jpg");//    //修改像素点
//    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);//重现QPicture的绘图指令QPainter painter(this);QPicture pic;pic.load("E:\\pic.zt");painter.drawPicture(0,0,pic);
}

19、QFile文件读写操作

文件QFile和文件信息读写QFileInfo

Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);//点击选取文件按钮,弹出文件对话框connect(ui->btn_file,&QPushButton::clicked,[=](){QString path = QFileDialog::getOpenFileName(this,"打开文件","E:\\1.Qt_temporary_files");//将路径放入到lineEditui->lineEdit->setText(path);//编码格式类//QTextCodec *codec = QTextCodec::codecForName("gbk");//读取内容,放入textEdit中QFile file(path);//参数就是读取文件的路径//设置打开方式file.open(QIODevice::ReadOnly);//QByteArray array = file.readAll();//按行读取QByteArray array;while(!file.atEnd()){array += file.readLine();}//将读入的数据放入textEditui->textEdit->setText(array);//转成gbk格式,默认是utf-8格式//ui->textEdit->setText(codec->toUnicode(array));//对文件对象进行关闭file.close();//进行写文件
//                file.open(QIODevice::Append);//用追加的方式进行写
//                file.write("aaaaaa");
//                file.close();//QFileInfo读取文件信息QFileInfo info(path);qDebug()<<"大小:"<<info.size()<<"后缀名:"<<info.suffix()<<"文件名:"<<info.fileName();qDebug()<<"创建日期:"<<info.birthTime().toString("yyyy/MM/dd hh:mm:ss");});
}

20、翻金币项目

翻金币提取码: z95t

打包后的游戏提取码: h327

***问题总结

1、因为有的函数没有自动补全,所以按照网上操作改了一些插件导致后面设计界面打不开,只能右键选中Qt designer打开,点击帮助,插件,把Qt Creator插件全部勾上就可以了。(我也不知道为什么,重启就没有了)

2、Qt:无法定位程序输入点于动态链接库等。我是按照下面这个博客解决的

Qt:无法定位程序输入点于动态链接库等。_阿远苏喂喂的博客-CSDN博客_qt无法定位程序输入点于动态链接库

零基础Qt笔记<传智教育>Qt版本:2022 5.15相关推荐

  1. 产品基础学习笔记---传智教育

    以下为本人的学习笔记,如有侵权,请联系删除 一.认识产品经理 1.产品经理的职责 外包公司的产品经理职责 对接甲方客户提出的需求 产出符合客户要求的方案 跟进项目开发进度并定期同客户反馈 初创公司的产 ...

  2. qt学习笔记 来自B站【最新QT从入门到实战完整版|传智教育】

    最新QT从入门到实战完整版|传智教育 目录在这里 2022.2.4 day1 06 QPushButton创建 07 对象树 08 Qt的坐标系 09 信号和槽-点击按钮关闭窗口 10 自定义信号和槽 ...

  3. 博文推荐|传智教育 x Pulsar:互联网教育的未来

    关于 Apache Pulsar Apache Pulsar 是 Apache 软件基金会顶级项目,是下一代云原生分布式消息流平台,集消息.存储.轻量化函数式计算为一体,采用计算与存储分离架构设计,支 ...

  4. 传智教育1月12日在深交所成功挂牌上市,教育行业A股IPO第一股今诞生!

    今日(1月12日),国内IT职业培训行业头部企业--江苏传智播客教育科技股份有限公司(以下简称"传智教育"或"公司")正式在深交所中小板挂牌上市,股票简称&qu ...

  5. 课程升级丨传智教育产品经理V6.0课程,蓄势待发!

    现如今,数字化发展成为新趋势,互联网产品不断迭代创新,作为产品发展的"火车头",产品经理的工作职能在逐渐发生改变,对岗位要求更加具体和多元. 随着产品经理的人才增加,以及行业不断被 ...

  6. 速看丨传智教育全链路+UI/UE设计学科V6.0硬核来袭!

    梦,该如何去追? 都说城市安不下肉身,老家容不下灵魂,选择毕业后回老家偏安一隅,还是留在大城市努力拼搏,是每个年轻人一闭眼就要思考的问题. 每一份梦想都值得被尊重,每一份努力都值得被赞赏,但想留在大城 ...

  7. 【官宣】传智教育使命升级!

    2021年1月12日,传智教育正式上市,成为中国"教育行业A股IPO第一股". A股30年来没有一家教育企业能够以直接IPO的方式上市,传智教育的成功上市,离不开国家的认可.支持和 ...

  8. 传智教育自主研发的8本教材入选“十三五”职业教育国家规划教材书目

    近日,传智教育(传智播客)自主研发的8本教材成功入选"十三五"职业教育国家规划教材书目,包含6本电子信息大类教材和2本信息技术类教材. 据了解,教育部职业教育与成人教育司公布< ...

  9. 11岁过python1级_11岁表弟写的Python零基础入门笔记!

    一.Python输入与输出输出:使用print()函数. print()函数的基本语法格式如下:print(输出内容). 输出内容可以是数字和字符串(字符串需要用引号括起来),也可以是包含运算符的表达 ...

  10. SQL零基础学习笔记(一)

    真的不知道我写了这么多不同的的学习笔记又没用..开始SQL零基础学习笔记 百度百科:SQL(Structured Query Language)结构化查询语言,是一种数据库查询和程序设计语言,用于存取 ...

最新文章

  1. python【蓝桥杯vip练习题库】BASIC-27 2n皇后问题(八皇后问题 搜索)
  2. Java-POI操作excel清除单元格分行字符
  3. hashtable——散列表
  4. codeforces F.F. Teodor is not a liar! 最长不降子序列
  5. python 面向对象编程tcp_python 闯关之路三(面向对象与网络编程)
  6. linux slf4j找不到,slf4j+log4j2在tomcat8 下无日志输出
  7. Python 带界面的可执行程序
  8. vue-router学习第一天
  9. PLSQL导入SQL文件
  10. 宝马android系统升级,宝马史上最大规模软件升级,换新OS7系统和安卓Auto,您的换了吗...
  11. linux如何复制代码不乱码,网上复制代码要小心,很可能会带入乱码字符
  12. 电脑键盘打字跳转计算机,电脑键盘打字方法
  13. 统计学习之第四天(可汗学院公开课:统计学)
  14. ES6 isFinite()
  15. 按图搜索淘宝商品-item_search_img (拍立淘)
  16. 优麒麟20.10 wifi 开关打不开解决方案
  17. 下载python安装包--国内环境快速下载
  18. 为什么多看书不能提高写作水平?
  19. 0对任何数取余_初等数论_第五章__同余方程
  20. PUTTY连接之诡异现象:虚拟机连接方式

热门文章

  1. c语言编译器自带宏定义,C/C++中内置的宏定义
  2. 使用对象 url 显示图像(window.URL.createObjectURL的使用)
  3. 2021-10-31 拓展知识(vscode中的终端路径设置)
  4. 如果我们使用appserv环境包_发布php的文件夹在,appserv怎么使用
  5. 我的2016—“不平凡”的一年
  6. Linux迷你小shell
  7. freeswitch php监听,程序员罗杰-freeswitch对接asterisk压测
  8. QML键盘事件之Enter键无响应解决方法
  9. 我试了下《复仇者联盟》AI换脸系列,当了英雄的我现在很慌...
  10. 服务器修复英文怎么写,修复服务器,repair server,音标,读音,翻译,英文例句,英语词典...