2021.8.16课堂笔记

QMainWindow  、QWidget 、QDialog  这三个界面的区别?
其中QMainWindow一创建,它就包含菜单栏(menu)、工具栏(tool)、状态栏(status)、中心部分(centerwidget)。
QMainWindow创一个对象之后,它对象里就包含上述几个部分!

QPushButton*  button1  =  new  QPushButton(this); //这边就要考虑,这个按钮是否嵌套在主窗体里吗?

用代码写这个控件(部件)的时候,主要就是考虑窗口的嵌套还是独立窗口?

信号与槽函数: connect函数是用来连接信号与槽的函数!~

connect(sender, &sender::signalfunction,  recv, &recv::slotfunction);
第一个参数:表示的是发送信号的对象
第二个参数:表示的发送的信号(自定义信号和预定义信号两种)
第三个参数:表示的接收信号的对象
第四个参数:表示的接收者的所处理的槽函数(槽函数是接收者的成员函数)

connect(button1,  SIGNAL(clicked()),   this,  SLOT(clickButtonFunction()));  //QT5之前的版本
connect(button1, &QPushButton::clicked, this , &mainwindow::clickButtonFunction); //QT5之后的版本
==========================================================================
Qt的学习是在C++的基础上进行的拓展,怎么学好QT,就是把Qt的一些类记住就行了!~


==========================================================================
【事件机制】
定义:事件是对各种应用程序需要知道的由应用程序内部或者外部产生的事情或者动作的通称。 
 Qt中事件被封装成一个个对象,所有的事件均继承自抽象类QEvent。


【事件过滤】
label1->installEventFilter(this);  //这个函数表明label1这个对象注册了一个事件过滤器。被this(对象)进行管理!

所以一旦有事件到达的时候,先到this这边来处理了,然后根据你是否注册了,来进行判断后续eventFilter函数是否执行

============================================================
Qt的容器类提供了两种类型的迭代器:
1、Java风格迭代器 
2、STL风格迭代器

foreach是Qt向C++语言中添加的一个用来进行容器的顺序遍历的关键字,它使用预处理器来进行实施。


============================================================
Qt中提供了强大的2D绘图系统,可以使用相同的API在屏幕和绘图设备上进行绘制,它主要基于三个类: 
 Qpainter:用于执行绘图操作,其提供的 API 在 GUI 或 QImage、QOpenGLPaintDevice、QWidget 和QPaintDevice 显示图形(线、形状、渐变等)、文本和图像。
  
QPaintDevice:不直接绘制物理显示画面,而利用逻辑界面的中间媒介。例如,绘制矩形图形时,为了将对象绘制到 QWidget、QGLPixelBuffer、QImage、QPixmap、QPicture 等多种界面中间,必须使用 QPaintDevice。 

QPaintEngine:提供了一些接口,可以用于QPainter在不同的设备上进行绘制;
简单说:使用QPainter在QPainterDevice上面进行绘制,它们之间使用QPaintEngine进行通 讯


================================================================
【QPainter】
QPainter完成具体的绘制操作,提供了大量函数来完成大部分绘制工作。
例如:直线、曲线、圆形、弧形等,还可以用来绘制文本和图片。  
QPainter可以在继承自QPaintDevice类的任何对象上进行绘制操作。
QPainter(QPaintDevice *device)  
QPainter 一般在部件的绘图事件 paintEvent() 中进行绘制,首先创建QPainter对象,然后进行图形的绘制,最后记得销毁QPainter对象。当窗口程序需要升级或者重新绘制时,调用此成员函数。使用repaint()和update()后,调用函数paintEvent()。

【示例,在paintEvent()函数里】
    QPainter painter;                                                         //创建QPainter对象
    painter.begin(this);
    painter.drawLine(QPoint(20,0), QPoint(20,size().height()));
    painter.drawLine(QPoint(0,20), QPoint(size().width(),20));
    // painter.drawPixmap(QPoint(0,0),*pixmap);
    painter.drawImage(QPoint(60,60), image);

    painter.setPen(Qt::blue);
    painter.setFont(QFont("Arial", 30));
    painter.drawText(rect(), Qt::AlignCenter, "Qt");

    painter.end();                                                           //销毁QPainter对象
===================================================================
【什么时候调用paintEvent()函数】
重绘事件的处理函数 :paintEvent()  
1、当窗口部件第一次显示时,系统会自动产生一个绘图事件。  
2、repaint()与update()函数被调用时。  
3、当窗口部件被其他部件遮挡,然后又再次显示出来时,就会对隐藏的区域产生一个重绘事件。  
4、重新调整窗口大小


【QPen】
void Widget::paintEvent(QPaintEvent* event)
{
    QPainter painter;
    painter.begin(this);
    //设置画笔的两种写法
    //第一种:构造函数传参进行画笔的设置
    QPen pen(Qt::green, 3, Qt::DashDotLine, Qt::RoundCap, Qt::RoundJoin);
    painter.setPen(pen);
    painter.drawLine(QPoint(20,0), QPoint(20, width()));
    //第二种:调用QPen的成员函数进行画笔的设置
    QPen pen1; // creates a default pen
    pen1.setStyle(Qt::DashDotLine);
    pen1.setWidth(3);
    pen1.setBrush(Qt::green);
    pen1.setCapStyle(Qt::RoundCap);
    pen1.setJoinStyle(Qt::RoundJoin);
    painter.setPen(pen1);
    painter.drawLine(QPoint(80,0), QPoint(80, width()));
    painter.end();
}

【QBrush】
    QPainter painter;
    painter.begin(this);
    QBrush brush(QColor(0, 0, 255), Qt::Dense4Pattern);//创建画刷
    painter.setBrush(brush); //使用画刷
    painter.drawEllipse(300, 20, 100, 100); //绘制椭圆
    //设置纹理
    brush.setTexture(QPixmap(":/myimage/image/2.png"));
    //重新使用画刷
    painter.setBrush(brush);
    //定义四个点
    static const QPointF points[4] = { QPointF(270.0, 80.0), QPointF(290.0, 10.0), QPointF(350.0, 30.0), QPointF(390.0, 70.0) };
    //使用四个点绘制多边形
    painter.drawPolygon(points, 4);
    painter.end();

==============================================
【drawText绘制文本】
void Widget::paintEvent(QPaintEvent* event)
{
    QPainter painter;
    painter.begin(this);

    // 设置画笔颜色
    painter.setPen(QColor(0, 160, 230));
    // 绘制区域为当前界面的整个区域(默认-左上角开始)
    painter.drawText(rect(), tr("1、看这里"));
    // 绘制区域从x坐标100,y坐标100处开始
    painter.drawText(100, 100, tr("2、从这里开始"));
    // 绘制区域从坐标点(20, 200)处开始
    painter.drawText(QPoint(20, 200), tr("加油!奋斗!"));

    painter.end();

}

===================================================
Qt提供了4个处理图像的类: Qimage,QPixmap,QBitmap和QPicture。  
1、QImage优化了 I/O操作,可以直接存取操纵像素数据;  
2、QPixmap主要用来在屏幕上显示图像;  
3、QBitmap从QPixmap继承,只能表示两种颜色;  
4、QPicture是可以记录和重放QPainter命令的类。
【重点】QImage和QPixmap可以相互转化,通常QImage载入图像并进行直接操作,然后转换为QPixmap在屏幕上显示。如果不需要操作像素,就直接使用QPixmap

======================================================
QIODevice子类:
1)QBuffer:读写QByteArray;  
2)QProcess:运行外部程序,处理进程间通讯;
3)QFileDevice:Qt5新增加的类,提供了有关文件操作的通用实现。
 ->QFlie:访问本地文件或者嵌入资源;  
 ->QTemporaryFile:创建和访问本地文件系统的临时文件;
4)QTcpSocket:TCP协议网络数据传输;
5)QUdpSocket:传输 UDP 报文;
6)QSslSocket:使用 SSL/TLS 传输数据;
=====================================================
【QTextStream写入文件例子】
QFile file("test.txt");
    if(file.open(QFile::WriteOnly|QFile::Truncate))
    {
        //定义一个out对象,往文件里写数据
        QTextStream out(&file);
        //设置写入数据的格式是16进制的
        out.setIntegerBase(16);
        //往文件里写入数据12345678
        out<<12345678;

        //又往文件里写入数据,设置写入数据的宽度,qSetFieldWidth来设置
        out<<"Result:"<<qSetFieldWidth(10)<<left<<3.14<<2.7;

        out.setFieldWidth(10);
        //用*来填充空的地方
        out.setFieldAlignment(QTextStream::AlignLeft);
        out.setPadChar('*');
        out<<3.14<<2.7;
    }

==========================================================
(1) 查询Student数据库。查询students表中各个同学的姓名和总学分。
SELECT name,totalscore FROM students
(2) 查询表中所有记录。查询students表中各个同学的所有信息。
SELECT * FROM students
(3) 条件查询。查询students表中总学分大于等于120的同学的情况。
SELECT * FROM students WHERE totalscore >= 120
(4) 多重条件查询。查询students表中所在系为“计算机”且总学分大于等于120的同学的情况。
SELECT * FROM students WHERE department='计算机' AND totalscore >= 120
(5) 使用LIKE谓词进行模式匹配。查询students表中姓“王”且单名的学生情况。
SELECT * FROM students WHERE name LIKE '王_'
(6) 用BETWEEN…AND指定查询范围。查询students表中不在1979年出生的学生情况。
SELECT * FROM students WHERE birthday NOT BETWEEN '1979-1-1' and '1979-12-31'
(7) 空值比较。查询总学分尚不定的学生情况。
SELECT * FROM students  WHERE totalscore IS NULL
(9)自然连接查询。查找计算机系学生姓名及其“C程序设计”课程的考试分数情况。
SLELCT name,grade FROM students, courses,grades, WHERE department = '计算机' AND coursename= ' C程序设计' AND students.studentid = grades.studentid AND courses.courseid = grades.coursesid

IN子查询。查找选修了课程号为101的学生情况。
SELECT * FROM students  WHERE studentid IN  ( SELE在执行包含子查询的SELECT语句时,系统先执行子查询,产生一个结果表,
再执行外查询。本例中,先执行子查询:
SELECT studentid FROM courses, students,grades WHERE courseid = '101' AND students.studentid = grades.studentid AND courses.courseid =grades.coursesid

(10) 比较子查询。这种子查询可以认为是IN子查询的扩展,它使表达式的值与子查询的结果进行比较运算。查找课程号206的成绩不低于课程号101的最低成绩的学生学号。
SELECT studentid FROM grades WHERE courseid = '206' AND grade !< ANY ( SELECT grade FROM grades WHERE courseid = '101'
)
(11) EXISTS子查询。EXISTS谓词用于测试子查询的结果是否为空表,若子查询的结果集不为空,则EXISTS返回TRUE,否则返回FALSE。EXISTS还可与NOT结合使用,即NOT EXISTS,其返回值与EXISTS刚好相反。查找选修206号课程的学生姓名。
SELECT name FROM students WHERE EXISTS ( SELECT * FROM grades WHERE studentid = students.studentid AND courseid = '206' 
)

(12) 查找选修了全部课程的同学姓名(即查找没有一门功课不选修的学生)。
SELECT name FROM students
WHERE NOT EXISTS
( SELECT * FROM courses
WHERE NOT EXISTS
( SELECT * FROM grades
WHERE studentid= students.studentid 
AND courseid=courses.courseid
) )

(13) 查询结果分组。将各课程成绩按学号分组。
SELECT studentid,grade FROM grades  GROUP BY studentid
(14) 查询结果排序。将计算机系的学生按出生时间先后排序。
SELECT * FROM students  WHERE department = '计算机'  ORDER BY birthday

==============================================
本例对Students数据库表执行查询,使用常用的聚合函数。
(1) 求选修101课程学生的平均成绩。
SELECT AVG(grade) AS ' 课程101平均成绩' FROM grades  WHERE courseid = '101'
(2) 求选修101课程学生的最高分和最低分。
SELECT MAX(grade) AS '课程101最高分' , MIN(grade) AS '课程101最低分' FROM grades  WHERE courseid = '101'
(3) 求学生的总人数。
SELECT COUNT(*) AS '学生总数' FROM students

==========================================
Qt自带的数据库SQLITE
QSqlDatabase类:
• 提供一个通过数据库连接访问数据库的接口。
• 一个QSqlDatabase的实例代表了一个数据库连接。
• 数据库连接通过数据库驱动提供对数据库的访问,数据库驱动继承自QSqlDriver。

一旦创建QSqlDatabase对象,就可以通过:
• setDatabaseName()
• setUserName()
• setPassword()
• setHostName()
• setPort()
• setConnectOptions()
• 来设置连接参数。然后调用 open() 方法打开数据库物理连接。在打开连接之前,连接不可用。

===========================================================
QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE", "conn1"); //连接哪个类型数据库QSQLTE
db.setHostName("127.0.0.1");  //设置连接属性
db.setDatabaseName("test");   //设置连接属性
db.setUserName("root");         //设置连接属性
db.setPassword("123");      //设置连接属性
bool ok = db.open();        //开始物理连接数据库
if(ok)
{
      qDebug()<<"打开数据库成功";
}
db.close();         //关闭数据库连接

=========================================================
    QSqlQuery query(db);
    query.exec("create table student(id int primary key,name varchar)");

    query.exec("insert into student values(1,'xiaopang')");
    query.exec("insert into student values(2,'xiaoming')");
    query.exec("insert into student values(3,'xiaohong')");
    db.close();         //关闭数据库连接

===========================================================
一、名称绑定
QSqlQuery query;
query.prepare("INSERT INTO T_STUDENT (name, age) VALUES (:name, :age)");
query.bindValue(":name", "小王"); //在绑定要插入的值
query.bindValue(":age", 11);
query.exec();
二、位置绑定
QSqlQuery query;
query.prepare("INSERT INTO T_STUDENT (name,age) VALUES (?,?)"); //准备执行
SQL查询
query.addBindValue("小王"); //在绑定要插入的值
query.addBindValue(11);
query.exec();

============================================================
视图:
基于QAbstractItemView抽象基类。 
• QListView:显示项目列表;
• QTableView:从一个表模型中显示数据;
• QTreeView:显示了层次列表的数据模型项目。

SQL模型类
• QSqlQueryModel:sql查询模型
• QSqlTableModel:sql表格模型
• QSqlRelationalTableModel:sql关系表格模型

===============================================================
QSqlTableModel类使用:
(1)新建模型;
(2)设置要操作的数据库表settalbe(),并没有从表中选择数据,而是获取
它的字段信息。
(3)用表中的数据填充模型,调用 select()。
设置表后,我们就可以应用QSqlTableModel模型进行数据库的基本操作了,
即增、删、改、查。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值