#include "widget.h"
#include "ui_widget.h"
#include<QObject>
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
QTimer *t1=new QTimer(this);
connect(t1,&QTimer::timeout,[=]()
{
update();
});
t1->start(1000);
}
Widget::~Widget()
{
delete ui;
}
void Widget::paintEvent(QPaintEvent *event)
{
QPainter painter(this); //实例化一个画家
//准备画笔
QPen pen;
pen.setStyle(Qt::SolidLine); //使用的是实线
pen.setColor(QColor("black")); //设置画笔颜色
pen.setWidth(5); //设置画笔的粗细
//画家拿起笔
painter.setPen(pen);
//设置画家的坐标起始点
painter.translate(width()/2,height()/2);
//绘制一个椭圆
painter.drawEllipse(QPoint(0,0),160,160);
painter.drawPoint(0,0);
//画刻度
painter.drawLine(0,-160,0,-140);
int line_h;
//循环60次每次代表刻度盘上的一个刻度
for(int i=1;i<=60;i++)
{
line_h=-150; //短刻度
painter.save(); //保存上一次的
//每次旋转6度
painter.rotate(i*6);
if(i%5==0)
{
line_h =-140; //长刻度
painter.drawText(-5,-125,tr("%1").arg(i/5)); //画文本
}
//绘制刻度线
painter.drawLine(0,-160,0,line_h);
painter.restore();
}
//获取系统时间
QTime systime =QTime::currentTime();
//画秒针
painter.save(); //保存之前操作
painter.rotate(6.0*systime.second());
pen.setWidth(2); //粗细
pen.setColor(QColor("pink"));
painter.setPen(pen); //画家拿起笔
painter.drawLine(0,0,0,-100);
painter.restore(); //恢复
//画分针
painter.save();
painter.rotate(6.0*systime.minute()+6.0*systime.second()/60);
pen.setWidth(4); //粗细
pen.setColor(QColor("green"));
painter.setPen(pen); //画家拿起笔
painter.drawLine(0,0,0,-80);
painter.restore();
//画时针
painter.save();
painter.rotate(30*systime.hour()+6.0*systime.minute()/60);
pen.setWidth(6); //粗细
pen.setColor(QColor("red"));
painter.setPen(pen); //画家拿起笔
painter.drawLine(0,0,0,-40);
painter.restore();
}
1>指针与引用的区别
1>指针定义时需要使用*号,引用定义时需要使用&。
2>指针取值需要使用*号运算符完成,引用使用时直接跟目标使用方式一致
3>指针定义时,需要给指针分配内存空间8字节,引用定义时不需要分配内存空间,引用使用的是目标的空间
4>指针初始化后,可以改变指针的指向,但是引用初始化后,不能在改变目标了
5>指针有二级指针,但是引用没有二级引用
6>有空指针,但是没有空引用
7>指针进行偏移运算时是对内存地址的偏移,而引用进行偏移时,就是对目标值的偏移指针不能指向右值,但是右值引用的目标可以是右值
8>指针定义时可以不初始化(野指针),引用定义时必须初始化
9>指针可以有指针数组,但是引用不能定义引用数组
2>c与c++区别
C语言是一种低级的、结构化的编程语言,主要用于系统底层编程和嵌入式开发。它的特点是效率高,接近机器指令,但也较为原始,需要程序员手动管理内存和数据结构。C++是对C语言的扩展,它是C加上面向对象特性的编程语言。C++引入了类、封装、继承和多态等OO特性,使得程序更易维护和复用,同时也保留了C语言的高效性和灵活性。
主要的区别有:
1. 语法扩展: C++增加了类、模板、命名空间等高级特性,而C没有这些。
2. 面向对象编: C++支持OOP的设计模式,C则更偏向过程化编程。
3. 异常处理: C++支持异常处理,而C没有内置异常处理机制。
4. 内存管理: C++提供了一些更友好的内存管理工具,如智能指针,而C需要手动分配和释放内存。
3>对qt哪些控件比较熟悉
1. QLabel: 显示静态文本或HTML内容的标签。
2. QPushButton: 提供点击交互的按钮。
3. QLineEdit: 用户输入框,用于文本输入。
4. QComboBox: 下拉列表,可以选择预设选项。
5. QTextEdit: 多行文本编辑器,类似富文本编辑器。
6. QScrollArea: 可滚动区域,包含内部控件。
7. QTabWidget: 用于组织多个面板的容器。
4>描述一下qt信号与槽机制
1> 原理
一个组件用于发射信号,与之绑定的组件收到信号后,会立刻做出相应
2> 信号:
所谓信号,就是信号函数,定义在类的signals权限下,是一个不完整的函数,只有函数声明,没有函数定义。返回值类型为void
信号函数不能当作普通函数一样被调用,只能被发射出去。
3> 槽:
所谓槽,就是槽函数,定义在类的slots权限,是一个完整的函数,既有函数声明,也有函数定义,返回值类型为void
槽函数可以当作普通函数一样被调用,但是普通函数不能当作槽函数接收信号
5>描述qt中对象树模型
1> 在对象树模型中,子组件构造时,需要指定父组件而存在
2> 子组件的生命周期由父组件进行管理
3> 当父组件展示时,会将子组件一并展示,当父组件释放空间时,会将加载在该组件上的所有子组件的空间全部释放
4> 对象树模型保证了,各个组件的内存不会泄露
5> 在栈区申请的组件,程序结束后,由系统自动回收,在堆区申请的组件,结束后,由其父组件进行回收资源
6> 父组件和子组件要用于共同的祖先类,实现的理论基础为多态
7> 每一个组件中都会拥有一个父组件指针和一个子组件链表
6>什么情况下需要使用多线程
在以下情况下,通常会选择使用多线程:
1. 并发处理: 当一个应用程序需要同时执行多个任务,例如网络请求、用户界面交互和后台计算等,如果把这些任务放在单个线程中会阻塞主线程导致用户体验下降,这时可以利用多线程来并行执行。
2. 资源利用:在I/O密集型任务中,如文件读写、数据库查询等,由于大部分时间都在等待外部资源响应,线程可以暂时释放CPU资源去做其他事情。
7>多线程需要注意什么
1. 线程安全问题: 不同线程间的数据共享可能导致竞态条件、死锁等问题,需要恰当使用互斥锁、信号量等同步机制保护关键代码。
2. 线程间的通信: 线程间需要有效沟通协作,使用线程池管理、条件变量、管道或消息队列等方式进行。
3. 资源消耗: 创建过多线程会增加系统资源消耗,包括内存和调度开销,因此需要合理设计线程的数量和生命周期。
4. 避免过度同步: 避免不必要的同步,过多的锁竞争可能导致性能下降。
5. 调试复杂性: 调试多线程程序相对困难,因为线程的行为很难预测和追踪。
8>Epoll,select,poll的区别
Select、poll、epoll是Linux系统中常见的三种I/O多路复用机制,它们的主要区别体现在文件描述符的处理、效率、以及支持的功能上
区别
1>Select文件描述符数量存在限制,通常为1024.效率较低,每次调用需将文件描述符集合从用户态拷贝到内核态,并遍历所有文件描述符,使用轮询方式检查所有文件描述符 触发方式:水平触发 每次I/O事件都需要系统调用 比较使用与小规模连接与简单并发场景
2>poll与select相比时没有文件描述符数量限制,其他一样
3>epoll 没有文件描述符的限制,支持大量文件描述符,只对激活了的文件描述符进行操作,支持水平触发和边缘触发
9>智能指针,区别
独占智能指针会“拥有”它所指向的对象,某一时刻,只能有一个unique_ptr指向给定的对象,当该指针被销毁时,指向的对象也会随之释放。
shared_ptr共享他指向的对象,多个共享指针可以指向(关联)相同的对象,在内部采用计数器机制来实现
当新的shared_ptr与对象关联时,引用计数器增加1
当shared_ptr超出作用域时,引用计数器减1
当引用计数器变为0时,则表示没有任何shared_ptr与对象关联,则释放该对象
10>共享队列和消息内存的区别
共享队列和消息内存都是进程间通信的机制,它们之间的区别主要在于数据组织和访问方式:
1. 共享队列是一种基于文件系统的 IPC 方法。它允许不同进程之间传递数据,通过读写操作将数据添加到队列的一端,从另一端取出。共享队列的数据通常是有序的,适合需要按照顺序处理任务的场景。进程对队列的访问通常需要锁来进行同步。
2. 消息内存:更像是一块公共区域,每个进程可以将自己的数据放入这个区域,并指明接收者。消息内存通常是无序的,因为消息的存储位置不受控制,而需要接收进程遍历查找。它适用于需要异步通信,消息发送者不需要立即得到响应的情况。
区别总结:
- 数据结构:共享队列是线性的,消息内存是非线性的。
- 访问模式:共享队列是先入先出,消息内存不确定。
- 同步需求:共享队列通常需要同步,保证数据完整性;消息内存强调松散耦合,无须即时响应。