2024年最全QT使用教程(五)之程序编写_qt4教程(1),2024年最新网络安全架构师成长路线

一、网安学习成长路线图

网安所有方向的技术点做的整理,形成各个领域的知识点汇总,它的用处就在于,你可以按照上面的知识点去找对应的学习资源,保证自己学得较为全面。
在这里插入图片描述

二、网安视频合集

观看零基础学习视频,看视频学习是最快捷也是最有效果的方式,跟着视频中老师的思路,从基础到深入,还是很容易入门的。
在这里插入图片描述

三、精品网安学习书籍

当我学到一定基础,有自己的理解能力的时候,会去阅读一些前辈整理的书籍或者手写的笔记资料,这些笔记详细记载了他们对一些技术点的理解,这些理解是比较独到,可以学到不一样的思路。
在这里插入图片描述

四、网络安全源码合集+工具包

光学理论是没用的,要学会跟着一起敲,要动手实操,才能将自己的所学运用到实际当中去,这时候可以搞点实战案例来学习。
在这里插入图片描述

五、网络安全面试题

最后就是大家最关心的网络安全面试题板块
在这里插入图片描述在这里插入图片描述

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化资料的朋友,可以点击这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

3 对象模型(对象树)

在Qt中创建对象的时候会提供一个Parent对象指针,下面来解释这个parent到底是干什么的。

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

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

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

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

这种机制在 GUI 程序设计中相当有用。例如,一个按钮有一个QShortcut(快捷键)对象作为其子对象。当我们删除按钮的时候,这个快捷键理应被删除。这是合理的。

4、QWidget是能够在屏幕上显示的一切组件的父类。

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

6、当然,我们也可以自己删除子对象,它们会自动从其父对象列表中删除。比如,当我们删除了一个工具栏时,其所在的主窗口会自动将该工具栏从其子对象列表中删除,并且自动调整屏幕显示。

Qt 引入对象树的概念,在一定程度上解决了内存问题。

1、当一个QObject对象在堆上创建的时候,Qt 会同时为其创建一个对象树。不过,对象树中对象的顺序是没有定义的。这意味着,销毁这些对象的顺序也是未定义的。

2、任何对象树中的 QObject对象 delete 的时候,如果这个对象有 parent,则自动将其从 parent 的children()列表中删除;如果有孩子,则自动 delete 每一个孩子。Qt 保证没有QObject会被 delete 两次,这是由析构顺序决定的。

如果QObject在栈上创建,Qt 保持同样的行为。正常情况下,这也不会发生什么问题。来看下下面的代码片段:

{
    QWidget window;
    QPushButton quit("Quit", &window);
}

作为父组件的 window 和作为子组件的 quit 都是QObject的子类(事实上,它们都是QWidget的子类,而QWidget是QObject的子类)。这段代码是正确的,quit 的析构函数不会被调用两次,因为标准 C++要求,局部对象的析构顺序应该按照其创建顺序的相反过程。因此,这段代码在超出作用域时,会先调用 quit 的析构函数,将其从父对象 window 的子对象列表中删除,然后才会再调用 window 的析构函数。

但是,如果我们使用下面的代码:

{
    QPushButton quit("Quit");
    QWidget window;
    quit.setParent(&window);
}

情况又有所不同,析构顺序就有了问题。我们看到,在上面的代码中,作为父对象的 window 会首先被析构,因为它是最后一个创建的对象。在析构过程中,它会调用子对象列表中每一个对象的析构函数,也就是说, quit 此时就被析构了。然后,代码继续执行,在 window 析构之后,quit 也会被析构,因为 quit 也是一个局部变量,在超出作用域的时候当然也需要析构。但是,这时候已经是第二次调用 quit 的析构函数了,C++ 不允许调用两次析构函数,因此,程序崩溃了。

由此我们看到,Qt 的对象树机制虽然帮助我们在一定程度上解决了内存问题,但是也引入了一些值得注意的事情。这些细节在今后的开发过程中很可能时不时跳出来烦扰一下,所以,我们最好从开始就养成良好习惯,在 Qt 中,尽量在构造的时候就指定 parent 对象,并且大胆在堆上创建。

4 信号和槽机制

信号槽是 Qt 框架引以为豪的机制之一。所谓信号槽,实际就是观察者模式。当某个事件发生之后,比如,按钮检测到自己被点击了一下,它就会发出一个信号(signal)。这种发出是没有目的的,类似广播。如果有对象对这个信号感兴趣,它就会使用连接(connect)函数,意思是,将想要处理的信号和自己的一个函数(称为槽(slot))绑定来处理这个信号。也就是说,当信号发出时,被连接的槽函数会自动被回调。这就类似观察者模式:当发生了感兴趣的事件,某一个操作就会被自动触发。

4.1 系统自带的信号和槽

下面我们完成一个小功能,上面我们已经学习了按钮的创建,但是还没有体现出按钮的功能,按钮最大的功能也就是点击后触发一些事情,比如我们点击按钮,就把当前的窗口给关闭掉,那么在Qt中,这样的功能如何实现呢?

其实无法两行代码就可以搞定了,我们看下面的代码

  QPushButton * quitBtn = new QPushButton("关闭窗口",this);
  connect(quitBtn,&QPushButton::clicked,this,&MyWidget::close);

第一行是创建一个关闭按钮,这个之前已经学过,第二行就是核心了,也就是信号槽的使用方式

connect()函数最常用的一般形式:

connect(sender, signal, receiver, slot);

参数解释:

sender:发出信号的对象

signal:发送对象发出的信号

receiver:接收信号的对象

slot:接收对象在接收到信号之后所需要调用的函数(槽函数)

那么系统自带的信号和槽通常如何查找呢,这个就需要利用帮助文档了,在帮助文档中比如我们上面的按钮的点击信号,在帮助文档中输入QPushButton,首先我们可以在Contents中寻找关键字 signals,信号的意思,但是我们发现并没有找到,这时候我们应该想到也许这个信号的被父类继承下来的,因此我们去他的父类QAbstractButton中就可以找到该关键字,点击signals索引到系统自带的信号有如下几个

这里的clicked就是我们要找到,槽函数的寻找方式和信号一样,只不过他的关键字是slot。

程序如下:

4.2 自定义信号和槽

使用connect()可以让我们连接系统提供的信号和槽。但是,Qt 的信号槽机制并不仅仅是使用系统提供的那部分,还会允许我们自己设计自己的信号和槽。

下面我们看看使用 Qt 的信号槽:

首先定义一个学生类和老师类:
	老师类中声明信号 饿了 hungry
signals:
       void hungury();
	学生类中声明槽   请客 treat
       public slots:
       void treat();


在窗口中声明一个公共方法下课,这个方法的调用会触发老师饿了这个信号,而响应槽函数学生请客
	void MyWidget::ClassIsOver()
      {
          //发送信号
           emit teacher->hungury();
       }
学生响应了槽函数,并且打印信息
         //自定义槽函数 实现
        void Student::eat()
      {
            qDebug() << "该吃饭了!";
        }
在窗口中连接信号槽
    teacher = new Teacher(this);
    student = new Student(this);

    connect(teacher,&Teacher::hungury,student,&Student::treat);
并且调用下课函数,测试打印出 “该吃饭了”


自定义的信号 hungry带参数,需要提供重载的自定义信号和 自定义槽
void hungury(QString name);  自定义信号
void treat(QString name );    自定义槽
但是由于有两个重名的自定义信号和自定义的槽,直接连接会报错,所以需要利用函数指针来指向函数地址, 然后在做连接
void (Teacher:: * teacherSingal)(QString) = &Teacher::hungury;
void (Student:: * studentSlot)(QString) = &Student::treat;
connect(teacher,teacherSingal,student,studentSlot);

自定义信号槽需要注意的事项:

1、发送者和接收者都需要是QObject的子类(当然,槽函数是全局函数、Lambda 表达式等无需接收者的时候除外);

2、信号和槽函数返回值是 void

3、信号只需要声明,不需要实现

4、槽函数需要声明也需要实现

5、槽函数是普通的成员函数,作为成员函数,会受到 public、private、protected 的影响;

6、使用 emit 在恰当的位置发送信号;

7、使用connect()函数连接信号和槽。

8、任何成员函数、static 函数、全局函数和 Lambda 表达式都可以作为槽函数

9、信号槽要求信号和槽的参数一致,所谓一致,是参数类型一致。

10、如果信号和槽的参数不一致,允许的情况是,槽函数的参数可以比信号的少,即便如此,槽函数存在的那些参数的顺序也必须和信号的前面几个一致起来。这是因为,你可以在槽函数中选择忽略信号传来的数据(也就是槽函数的参数比信号的少)。

4.3信号槽的拓展

1、一个信号可以和多个槽相连

如果是这种情况,这些槽会一个接一个的被调用,但是它们的调用顺序是不确定的。

2、多个信号可以连接到一个槽

只要任意一个信号发出,这个槽就会被调用。

3、一个信号可以连接到另外的一个信号

当第一个信号发出时,第二个信号被发出。除此之外,这种信号-信号的形式和信号-槽的形式没有什么区别。

4、槽可以被取消链接

这种情况并不经常出现,因为当一个对象delete之后,Qt自动取消所有连接到这个对象上面的槽。

5、信号槽可以断开

利用disconnect关键字是可以断开信号槽的

6、使用Lambda 表达式

在使用 Qt 5 的时候,能够支持 Qt 5 的编译器都是支持 Lambda 表达式的。

在连接信号和槽的时候,槽函数可以使用Lambda表达式的方式进行处理。后面我们会详细介绍什么是Lambda表达式

4.4 Qt4版本的信号槽写法

connect(zt,SIGNAL(hungry(QString)),st,SLOT(treat(QString)));

这里使用了SIGNAL和SLOT这两个宏,将两个函数名转换成了字符串。注意到connect()函数的 signal 和 slot 都是接受字符串,一旦出现连接不成功的情况,Qt4是没有编译错误的(因为一切都是字符串,编译期是不检查字符串是否匹配),而是在运行时给出错误。这无疑会增加程序的不稳定性。

给大家的福利

零基础入门

对于从来没有接触过网络安全的同学,我们帮你准备了详细的学习成长路线图。可以说是最科学最系统的学习路线,大家跟着这个大的方向学习准没问题。

同时每个成长路线对应的板块都有配套的视频提供:

在这里插入图片描述

因篇幅有限,仅展示部分资料

网络安全面试题

绿盟护网行动

还有大家最喜欢的黑客技术

网络安全源码合集+工具包

所有资料共282G,朋友们如果有需要全套《网络安全入门+黑客进阶学习资源包》,可以扫描下方二维码领取(如遇扫码问题,可以在评论区留言领取哦)~

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化资料的朋友,可以点击这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

  • 30
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要使qt chart的网格填满整个窗口,可以按照以下步骤进行: 1. 在Qt Creator中创建一个新的Qt Widgets应用程序。 2. 打开.ui文件,在设计器中添加一个QChartView控件。 3. 在代码中创建一个QChart对象,并将其设置为QChartView的图表。 4. 将图表的背景颜色设置为白色或其他你想要的颜色。 5. 设置图表的网格线颜色、线宽和线型。 6. 将QChartView控件的布局设置为QVBoxLayout。 7. 将QChartView控件添加到布局中。 8. 将QWidget的背景颜色设置为白色或其他你想要的颜色。 9. 在QWidget上设置布局为QVBoxLayout。 10. 将QChartView控件添加到QWidget的布局中。 11. 在QWidget上设置布局的对齐方式为Qt::AlignCenter。 12. 在QWidget的resizeEvent()函数中重新计算图表的大小,并调用QChartView的resize()函数。 以下是示例代码: ```cpp #include <QtWidgets/QApplication> #include <QtWidgets/QMainWindow> #include <QtCharts/QChartView> #include <QtCharts/QLineSeries> #include <QtCharts/QValueAxis> #include <QtCharts/QCategoryAxis> #include <QtCharts/QChart> QT_CHARTS_USE_NAMESPACE int main(int argc, char *argv[]) { QApplication a(argc, argv); QMainWindow mainWindow; // 创建图表和系列 QChart *chart = new QChart(); QLineSeries *series = new QLineSeries(); series->append(0, 6); series->append(2, 4); series->append(3, 8); series->append(7, 4); series->append(10, 5); chart->addSeries(series); // 设置图表背景颜色 chart->setBackgroundBrush(QBrush(Qt::white)); // 设置网格线样式 QPen gridPen(QColor(221, 221, 221), 0.5, Qt::SolidLine); chart->axisX()->setGridLinePen(gridPen); chart->axisY()->setGridLinePen(gridPen); // 设置网格线数量 chart->axisX()->setTickCount(11); chart->axisY()->setTickCount(11); // 设置网格线范围 chart->axisX()->setRange(0, 10); chart->axisY()->setRange(0, 10); // 设置网格线标签格式 chart->axisX()->setLabelFormat("%.1f"); chart->axisY()->setLabelFormat("%.1f"); // 创建图表视图 QChartView *chartView = new QChartView(chart); // 将图表视图添加到主窗口 QVBoxLayout *layout = new QVBoxLayout(); QWidget *centralWidget = new QWidget(); centralWidget->setLayout(layout); layout->addWidget(chartView); centralWidget->setStyleSheet("background-color: white;"); mainWindow.setCentralWidget(centralWidget); // 设置布局对齐方式 layout->setAlignment(Qt::AlignCenter); // 重新计算图表大小 QObject::connect(centralWidget, &QWidget::resizeEvent, [=](QResizeEvent *event) { QSizeF size = chartView->size(); size.setHeight(size.width() / chart->plotArea().width() * chart->plotArea().height()); chartView->resize(size.toSize()); }); mainWindow.show(); return a.exec(); } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值