qt学习——基本使用、对象树、按钮、信号与槽

news2024/11/18 21:35:27

初识qt

  • **qt**
    • **qt命名规范以及相关快捷键的使用**
    • **QPushButton**
    • **对象树**
    • **点击按钮关闭窗口**
    • **信号和槽**
    • **标准的信号和槽**
    • **自定义信号和槽**
    • **带参数的自定义信号和槽传参以及函数的二义性问题**

qt

qt命名规范以及相关快捷键的使用

优点:Qt相对于C++,有一个很好的机制是,他有自己的一套内存回收机制,在一定程度上简化了内存回收,不需要每每new申请之后总要想着delete了
widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>//包含头文件QWidget 窗口类

class Widget : public QWidget
{
    Q_OBJECT //Q_OBJECT宏,允许类中使用信号和槽的机制

public:
    Widget(QWidget *parent = nullptr);//构造函数
    ~Widget();//析构函数
};
#endif // WIDGET_H

main.cpp

#include "mywidget.h"

#include <QApplication>//包含一个应用程序类的头文件

//argc命令行变量的数量 argv命令行变量的数组

//应用程序对象,在Qt中,应用程序对象有且仅有一个
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    //窗口对象 myWidget父类 ->Qwidget
    myWidget w;
    //窗口对象默认不会显示,必须要调用show方法显示窗口
    w.show();
    //让应用程序对象 进入消息循环机制
    //让代码阻塞到这行
    return a.exec();
}

项目的代码解释
在这里插入图片描述
widget.cpp

#include "widget.h"

//命名规范
//类名 首字母大写,单词和单词之间首字母大写
//函数名 变量名称 首字母小写,单词和单词之间首字母大写
//快捷键
//注释ctrl +l
//运行ctrl + r
//编译ctrl + b
//字体缩放ctrl +鼠标滚轮
//查找 ctrl+f
//整行移动 ctrl+shift+上键或者下键
//帮助文档 F1
//自动对齐 ctrl+i;
//同名直接的.h和.cpp切换 F4
//帮助文档 第一种方式F1 
//第二种 左侧按钮
//第三种 路径方式

Widget::Widget(QWidget *parent)
    : QWidget(parent)//初始化列表
{
}

Widget::~Widget()
{
}

QPushButton

QPushButton是Qt框架中的一个类,用于创建一个可点击的按钮控件。可以设置按钮的文本、图标、样式等属性,以及连接按钮的点击事件到相应的槽函数。常用于创建用户界面中的交互按钮。
用到类的时候要将模块加入到项目里面
在Qt中,show()是QWidget类的一个成员函数,用于显示窗口小部件。当调用show()函数时,窗口小部件将被显示在屏幕上
在Qt中,QPushButton类确实有一个setParent()函数,可以用于设置按钮的父对象
与上一个一样,前面的头文件和main函数不变
父子关系:
默认情况下.按钮没有认干爹的情况,是顶层窗口
想要按钮显示在窗口上,就要跟窗口构造父子关系
1、setParent
2、构造函数传参

#include "widget.h"
#include <QPushButton>//按钮控件的头文件

//命名规范
//类名 首字母大写,单词和单词之间首字母大写
//函数名 变量名称 首字母小写,单词和单词之间首字母大写
//快捷键
//注释ctrl +l
//运行ctrl + r
//编译ctrl + b
//字体缩放ctrl +鼠标滚轮
//查找 ctrl+f
//整行移动 ctrl+shift+上键或者下键
//帮助文档 F1
//自动对齐 ctrl+i;
//同名直接的.h和.cpp切换 F4
//帮助文档 第一种方式F1
//第二种 左侧按钮
//第三种 路径方式

Widget::Widget(QWidget *parent)
    : QWidget(parent)//初始化列表
{
    //创建一个按钮
    QPushButton * btn=new QPushButton;
    //btn->show();//show的默认是按照顶层方式弹出的控件
    //让btn对象 依赖在Widget窗口中
    btn->setParent(this);
    //显示文本
    btn->setText("第一个按钮");

    //创建第二个按钮  按照控件的大小来创建窗口
    QPushButton * btn2=new QPushButton("第二个按钮",this);

    //移动btn2按钮
    //第二种方式传入的长和宽
    btn2->move(200,200);

    按钮可不可以 重新制定大小 可以
    //btn->resize(50,50);

    //重置窗口的大小
    //传入的是长和宽
    resize(600,400);

    //设置固定的窗口大小
    setFixedSize(600,400);
    
    //设置窗口的标题
    setWindowTitle("第一个窗口");
}

Widget::~Widget()
{
}

第一个窗口
在这里插入图片描述

#include "widget.h"
#include <QPushButton>
#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Widget w;

    //添加按钮
//    QPushButton btn;
//    btn.setText("按钮1");
//    //将按钮显示出来
//    btn.show();

    //默认情况下没有建立父子关系,显示的都是顶层窗口
    //要建立父子关系
    //1、setParent函数
    QPushButton btn;
    btn.setText("按钮1");
    btn.setParent(&w);//传入的是对象指针
    //2、构造函数传参
    QPushButton btn2("按钮2",&w);
    //移动一下按钮位置
    btn2.move(100,100);

    btn2.resize(400,400);

    //按钮3,和按钮2建立父子关系
    QPushButton btn3("按钮3",&btn2);
    btn3.move(100,100);

    //设置窗口标题
    w.setWindowTitle("hello world");

    //设置窗口的固定大小
    //w.setFixedSize(800,600);

    //同时设置窗口的位置和大小
    //move和resize的集合体
    w.setGeometry(400,400,500,500);

    w.show();

    //顶层窗口移动到200 100
    //是以父窗口的左上角为0,0
    //以向左的方向为x的正方向
    //以向右的方向为y的正方向
    //顶层窗口是以屏幕左上角为0,0
    //w.move(200,100);
    return a.exec();
}

在这里插入图片描述

对象树

对象树之间的父子关系是对象之间的父子关系 不是类直接的父子关系
父对象在释放析构函数的时候还会释放子对象
每个窗口都有child列表

在Qt中,对象树是一种管理对象生命周期的机制。当一个对象被添加到对象树中时,它的父对象会负责管理它的内存分配和释放。这意味着,当父对象被销毁时,它的所有子对象也会被自动销毁,从而避免了内存泄漏和悬挂指针等问题。
在创建一个新的Qt对象时,我们通常需要将它添加到对象树中,以便它能够被正确地管理。这可以通过将它的父对象作为参数传递给它的构造函数来实现。这样,当父对象被销毁时,它的子对象也会被自动销毁,从而保证了对象的正确释放。
总之,传入对象树是Qt中一种重要的管理对象生命周期的机制,可以有效地避免内存泄漏和悬挂指针等问题。

在qt中创建对象的时候会提供一个Parent对象指针,下面来解释这个parent到底是干什么的
QObject是以对象树的形式组织起来的。
当你创建一个QObject对象时,会看到QObject的构造函数接收一个
QObject指针作为参数,这个参数就是 parent,也就是父对象指针。
这相当于,在创建QObject对象时,可以提供一个其父对象,我们创建的这个QObject对象会自动添加到其父对象的children()列表。
当父对象析构的时候,这个列表中的所有对象也会被析构。(注意,这里的父对象并不是继承意义上的父类)
这种机制在GUI程序设计中相当有用。例如,一个按钮有一个QShoxtcut(快捷键)对象作为其子子对象。
当我们删除按钮的时候,这个快捷键理应被删除。这是合理的。

在这里插入图片描述
构造顺序从上到下,析构顺序从下到上
在这里插入图片描述

点击按钮关闭窗口

要四个元素:按钮、被点击、窗口、关闭
建立四者的关系
*QPushButton btn = new QPushButton(“按钮1”,this);为啥这段要传入this指针
在Qt中,每个QWidget派生类都有一个父对象,父对象负责管理其子对象的生命周期。在这个例子中,QPushButton的父对象是当前的QWidget,也就是说,当当前的QWidget被销毁时,它的所有子对象也会被自动销毁。因此,将当前QWidget的指针作为QPushButton的父对象传入,可以确保QPushButton的生命周期与当前QWidget的生命周期相同,避免了内存泄漏的问题。
*Widget::Widget(QWidget parent)
: QWidget(parent)这段代码什么意思
这段代码是一个构造函数,用于创建一个QWidget对象。其中,parent是QWidget对象的父对象,表示该QWidget对象是由哪个QWidget对象创建的。如果没有父对象,可以将parent设置为nullptr或省略。

#include "widget.h"
#include<QPushButton>

Widget::Widget(QWidget *parent)
    : QWidget(parent)
{
    QPushButton *btn = new QPushButton("按钮1",this);
    //关闭 this->close

    //建立四者的关系
    connect(btn,&QPushButton::clicked,this,&Widget::close);

}

Widget::~Widget()
{
}


信号和槽

信号和槽机制
信号:各种事件
槽:响应信号的动作
当某个事件发生后,如某个按钮被点击了一下,它就会发出一个被点击的信号(signal)
某个对象接收到这个信号之后,就会做一些相关的处理动作(称为槽slot)。
但是Qt对象不会无故收到某个信号,要想让一个对象收到另一个对象发出的信号,这时候需要建立连接(connect)

*QPushButton btn = new QPushButton(“按钮1”,this);
connect(btn,&QPushButton::clicked,this,&Widget::close);
这两句代码什么意思

这两句代码是在Qt框架下编写的,作用是创建一个名为"按钮1"的QPushButton对象,并将其添加到当前窗口中(this表示当前窗口),然后将该按钮的clicked信号与当前窗口的close槽函数连接起来。也就是说,当用户点击该按钮时,会触发clicked信号,从而执行当前窗口的close槽函数,关闭当前窗口。
具体来说,&QPushButton::clicked是一个信号,表示按钮被点击时会发出该信号;this是当前窗口的指针,表示将该信号连接到当前窗口上;&Widget::close是一个槽函数,表示当按钮被点击时会执行当前窗口的close槽函数,从而关闭当前窗口。
使用了函数指针。这里,我们将btn的clicked信号与Widget对象的close槽函数连接起来,使用了&QPushButton::clicked和&Widget::close来分别表示这两个函数的指针。

#include "widget.h"
#include<QPushButton>

Widget::Widget(QWidget *parent)
    : QWidget(parent)
{
    QPushButton *btn = new QPushButton("按钮1",this);
    //关闭 this->close
    
    //按钮
    //被点击
    //窗口
    //关闭
    
    //建立四者的关系
    connect(btn,&QPushButton::clicked,this,&Widget::close);
    
    //信号发送者
    //信号
    //信号接收者
    //槽:信号的处理动作
    //通过connect建立四者的关系
    //connect(信号发送者,信号,信号接收者,槽)
}

Widget::~Widget()
{
}


标准的信号和槽

具体有哪些:自己查
标准的槽
在这里插入图片描述
标准的信号
在这里插入图片描述
继承过来看父类

在这里插入图片描述

#include "widget.h"
#include<QPushButton>

Widget::Widget(QWidget *parent)
    : QWidget(parent)
{
    QPushButton *btn = new QPushButton("按钮1",this);
    //关闭 this->close

    //按钮
    //被点击
    //窗口
    //关闭

    //建立四者的关系
    //关闭
    //connect(btn,&QPushButton::clicked,this,&Widget::close);

    //最大化
    //connect(btn,&QPushButton::clicked,this,&Widget::showMaximized);
    
    //最小化
    connect(btn,&QPushButton::clicked,this,&Widget::showMinimized);

    //隐藏  但是在运行  任务管理器可以结束进程
    connect(btn,&QPushButton::clicked,this,&Widget::hide);
    
    //信号发送者
    //信号
    //信号接收者
    //槽:信号的处理动作
    //通过connect建立四者的关系
    //connect(信号发送者,信号,信号接收者,槽)
}

Widget::~Widget()
{
}

指针指向函数时,可以不加&符号,因为函数名本身就代表了函数的地址。
例如:

void func() {
    // do something
}

int main() {
    void (*p)() = func; // 不加&符号
    p(); // 调用函数
    return 0;
}

在上面的代码中,p 是一个指向函数的指针,它直接赋值为 func,不需要加上 & 符号
在这里插入图片描述

自定义信号和槽

在这里插入图片描述
在这里插入图片描述
从上到下依次为

#ifndef STUDENT_H
#define STUDENT_H

#include <QObject>

class Student : public QObject
{
    Q_OBJECT
public:
    explicit Student(QObject *parent = nullptr);

signals:

public slots:
    //学生请吃饭
    void treat();
};

#endif // STUDENT_H
#ifndef TEACHER_H
#define TEACHER_H

#include <QObject>

class Teacher : public QObject
{
    Q_OBJECT
public:
    explicit Teacher(QObject *parent = nullptr);

signals:
void hungry();

public slots:

};

#endif // TEACHER_H

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include "student.h"
#include "teacher.h"

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();

    void classIsOver();

private:
    Teacher *pTeacher;
    Student *pStudent;
};
#endif // WIDGET_H

#include "widget.h"

#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Widget w;
    w.show();
    return a.exec();
}

#include "student.h"
#include <QDebug>

Student::Student(QObject *parent) : QObject(parent)
{

}

void Student::treat()
{
    qDebug()<<"Student treat teacher";
}

#include "teacher.h"

Teacher::Teacher(QObject *parent) : QObject(parent)
{

}

#include "widget.h"

Widget::Widget(QWidget *parent)
    : QWidget(parent)
{
    //new的时候要加入对象树
    //老师和学生的两个对象创建
    pTeacher=new Teacher(this);
    pStudent=new Student(this);
    //建立连接
    connect(pTeacher,&Teacher::hungry,pStudent,&Student::treat);

    //下课了
    this->classIsOver();
}

void Widget::classIsOver()
{
    //触发老师饿了的信号
    emit pTeacher->hungry();
}

Widget::~Widget()
{
}




在这里插入图片描述

带参数的自定义信号和槽传参以及函数的二义性问题

在上面的场景再引入
在这里插入图片描述
void (Teacher::*teacher_qString)(QString)=&Teacher::hungry;啥意思
这行代码定义了一个指向 Teacher 类的成员函数的指针,该成员函数的参数为 QString 类型,函数名为 hungry。具体来说,Teacher::*teacher_qString 表示指向 Teacher 类的成员函数指针,QString 表示该成员函数的参数类型,&Teacher::hungry 表示该成员函数的地址。这个指针可以用来调用 Teacher 类的成员函数 hungry
函数重载是指在同一个作用域内定义了多个同名函数,但是它们的参数类型、个数或顺序不同。在调用这些同名函数时,编译器需要根据传入的参数类型、个数或顺序来确定调用哪一个函数。
使用函数指针可以解决函数重载问题,是因为函数指针是一个指向函数的指针变量,它指向的是函数的入口地址,而不是函数本身。因此,不同的函数可以有不同的入口地址,即使它们的函数名相同。通过定义不同的函数指针类型,可以指向不同的函数,从而实现函数重载的效果。
例如,假设有两个同名函数 foo,一个参数类型为 int,另一个参数类型为 float,可以定义两个不同的函数指针类型,分别指向这两个函数:
void (*foo_int)(int);
void (*foo_float)(float);
然后,根据需要,可以将不同的函数指针指向不同的函数,从而实现函数重载的效果:
void foo1(int x) { … }
void foo2(float x) { … }
foo_int = foo1;
foo_float = foo2;
foo_int(1); // 调用 foo1
foo_float(1.0); // 调用 foo2
在这里插入图片描述
student.h

#ifndef STUDENT_H
#define STUDENT_H
#include <QObject>

class Student : public QObject
{
    Q_OBJECT
public:
    explicit Student(QObject *parent = nullptr);

signals:

public slots:
    //学生请吃饭
    void treat();
    void treat(QString what);
};

#endif // STUDENT_H

teacher.h

#ifndef TEACHER_H
#define TEACHER_H

#include <QObject>

class Teacher : public QObject
{
    Q_OBJECT
public:
    explicit Teacher(QObject *parent = nullptr);

signals:
void hungry();
void hungry(QString what);

public slots:

};

#endif // TEACHER_H

wight.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include "student.h"
#include "teacher.h"

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();

    void classIsOver();

private:
    Teacher *pTeacher;
    Student *pStudent;
};
#endif // WIDGET_H

main.cpp

#include "widget.h"

#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Widget w;
    w.show();
    return a.exec();
}

student.cpp

#include "student.h"
#include <QDebug>

Student::Student(QObject *parent) : QObject(parent)
{

}

void Student::treat()
{
    qDebug()<<"Student treat teacher";
}

void Student::treat(QString what)
{
     qDebug()<<"Student treat teacher"<<what;
}


teacher.cpp

#include "teacher.h"

Teacher::Teacher(QObject *parent) : QObject(parent)
{

}

wight.cpp

#include "widget.h"

Widget::Widget(QWidget *parent)
    : QWidget(parent)
{
    //new的时候要加入对象树
    //老师和学生的两个对象创建
    pTeacher=new Teacher(this);
    pStudent=new Student(this);
    //建立连接
    //两个函数发生了重载
    //connect(pTeacher,&Teacher::hungry,pStudent,&Student::treat);

    //老师说要吃黄焖鸡,学生就请吃黄焖鸡
    //hungry里面多加入一个参数 Qstring类型
    //treat里面也需要传入一个参数 Qstring
    //因为函数发生了重载  所以要解决

    /*
     * 1、使用函数指针赋值  让编译器挑选符合类型
     * 2、使用static_cast 强制转换,也是让编译器自动挑选符合类型的函数
     */

   //传入的是string类型
   void (Teacher::*teacher_qString)(QString)=&Teacher::hungry;
   void (Student::*student_qString)(QString)=&Student::treat;
   connect(pTeacher,teacher_qString,pStudent,student_qString);

   //使用static_cast来转换无参的函数
   connect(pTeacher,
           static_cast <void (Teacher::*)()>(&Teacher::hungry),
           pStudent,
           static_cast <void (Student::*)()>(&Student::treat));
   
    //下课了
    this->classIsOver();
}

void Widget::classIsOver()
{
    //触发老师饿了的信号
    emit pTeacher->hungry();

    //带参数的信号发射
    emit pTeacher->hungry("黄焖鸡");
}

Widget::~Widget()
{
}

这里会发生函数重载有二义性 解决方法:
* 1、使用函数指针赋值 让编译器挑选符合类型
* 2、使用static_cast 强制转换,也是让编译器自动挑选符合类型的函数**

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/641580.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

华为OD机试真题 JavaScript 实现【狼羊过河】【2022Q4 100分】,附详细解题思路

一、题目描述 一农夫带着m只羊&#xff0c;n只狼过河&#xff0c;农夫有一条可载x只狼/羊的船&#xff1b;农夫在时或者羊的数量大于狼时&#xff0c;狼不会攻击羊&#xff1b; 农夫在不损失羊的情况下&#xff0c;运输几次可以完成运输&#xff1f; 返程不计入次数。 二、…

Vue中如何进行表单联动与级联选择?

Vue中如何进行表单联动与级联选择&#xff1f; 表单联动和级联选择是Vue.js中常见的功能。表单联动是指在一个表单中&#xff0c;当某一个输入框的值发生变化时&#xff0c;其他输入框的值也会随之改变。级联选择是指在一个选择框中&#xff0c;当选择一个选项时&#xff0c;另…

领域建模之数据模型设计方法论 | 京东云技术团队

本文通过实际业务需求场景建模案例&#xff0c;为读者提供一种业务模型向数据模型设计的方法论&#xff0c;用于指导实际开发中如何进行业务模型向数据模型转化抽象&#xff0c;并对设计的数据模型可用性、扩展性提供了建议性思考。通过文章&#xff0c;读者可以收获到业务模型…

linux 漏洞升级、初次安装 mysql

文章目录 适用安装遇到问题 适用 1、为解决Mysql漏洞而需要离线升级mysql版本&#xff1b; 2、初次安装Mysql也可以参考本文&#xff1b; 安装 提示&#xff1a;首次安装可跳过第二步、第三步 一、查看CentOS7系统自带mariadb # 查看系统自带的Mariadb [rootiZ2ze3hm3gyjy…

最全Java锁详解:独享锁/共享锁+公平锁/非公平锁+乐观锁/悲观锁

乐观锁 VS 悲观锁 乐观锁与悲观锁是一种广义上的概念&#xff0c;体现了看待线程同步的不同角度&#xff0c;在Java和数据库中都有此概念对应的实际应用。 1.乐观锁 顾名思义&#xff0c;就是很乐观&#xff0c;每次去拿数据的时候都认为别人不会修改&#xff0c;所以不会上…

英语中-后置定语

一般说来&#xff0c;形容词放在所修饰名词的前面。单个的现在分词、过去分词以及动名词作定语&#xff0c;都是放在所修饰名词&#xff08;或代词&#xff09;的前面。这些称为前置定语。 例如&#xff1a; a red flower/ an interesting story&#xff0c;这里red, interes…

SaaS人力资源管理系统的Bug

SaaS人力资源管理系统的Bug Bug1【18】 这里我是直接把代码复制过来的&#xff0c;然后就有一个空白 这是因为它的代码有问题&#xff0c;原本的代码如下所示 <el-table-column fixed type"index" label"序号" width"50"></el-table-co…

ssm+java在线考试批改阅卷系统

本次学校在线考试系统的实现过程&#xff0c;它的开发使用B/S结构即浏览器和服务器结构框架&#xff0c;采用SSM框架技术&#xff0c;数据库使用了mysql数据库&#xff0c;页面设计采用了MVC框架&#xff0c;后端采用了SSM框架技术scrip等其他一些脚本语言&#xff0c;使用到在…

hash算法详解

散列算法&#xff08;Hash Algorithm&#xff09;&#xff0c;又称哈希算法&#xff0c;杂凑算法&#xff0c;是一种从任意文件中创造小的数字「指纹」的方法。与指纹一样&#xff0c;散列算法就是一种以较短的信息来保证文件唯一性的标志&#xff0c;这种标志与文件的每一个字…

Java中的动态链接VS操作系统动态链接

在操作系统OS中为了优化内存的使用会采用一种动态链接方式&#xff0c;一个文件想要在操作系统中运行必须经过编译、汇编译、链接、装载等步骤。可以参考Java程序是怎么跑起来的。本篇主要讲解Java栈帧中动态链接部分与操作系统的的动态链接的区别与联系 操纵系统为什么需要动态…

2023年欧洲科学院院士中的华人学者简介

近日&#xff0c;2023年欧洲科学院新当选欧洲科学院院士名单出炉&#xff0c;由于入选学者接受邀请及注册的时间进度不同&#xff0c;入选名单陆续公布&#xff08;截止目前已更新135位&#xff09;。本文知识人网小编仅介绍入选名单中华人学者的情况。 欧洲科学院(Academia Eu…

优化--分类树,我从2s优化到0.1s

1.前言 分类树查询功能&#xff0c;在各个业务系统中可以说随处可见&#xff0c;特别是在电商系统中。 但就是这样一个简单的分类树查询功能&#xff0c;我们却优化了5次。 到底是怎么回事呢&#xff1f; 2.背景 我们的网站使用了SpringBoot推荐的模板引擎&#xff1a;Thym…

TiDB x Catalyst丨秒级洞悉数据价值,TiDB 帮助“客户成功 SaaS 厂商”提升用户体验

导读 Catalyst 是一家总部位于纽约的 SaaS 创业公司&#xff0c;它提供了一个直观且灵活的客户成功平台&#xff08;Custom Success Platform&#xff09;&#xff0c;可帮助客户成功团队汇聚客户数据&#xff0c;洞悉客户健康状况&#xff0c;推动客户留存和业务增长。目前 C…

「网络编程」第一讲:初识网络_网络基础1

「前言」文章是关于网络编程方面的&#xff0c;今天内容大致是网络基础&#xff0c;讲解下面开始&#xff01; 「归属专栏」网络编程 「笔者」枫叶先生(fy) 「座右铭」前行路上修真我 「枫叶先生有点文青病」 「每篇一句」 青山不改&#xff0c;绿水长流 ——白居易 目录 一、…

chatgpt赋能python:Python怎么建服务器?

Python怎么建服务器&#xff1f; 作为一名具有10年Python编程经验的工程师&#xff0c;我深入研究了Python的一些高级特性&#xff0c;其中包括Python如何建立服务器的方法。Python是一个高级的编程语言&#xff0c;可以轻松创建服务器应用程序&#xff0c;并为您的网站提供高…

redis中的intset集合源码阅读探究;基于7.0+版本

1丶什么是intset Redis 中的 intset&#xff08;整数集合&#xff09;是一种高效的数据结构选择。Intset 具有紧凑的内存布局和快速的插入、删除和查找操作&#xff0c;适用于存储大量整数&#xff0c;并且能够节省内存空间。 2丶先说优点 内存布局&#xff1a;Intset 的内存…

vue-element-admin项目-Host key verification failed.-已解决

在网上下载的element-admin项目&#xff0c;install的时候一直报错Host key verification failed&#xff0c; 实测好用&#xff01;&#xff01;&#xff01;已解决 报错问题&#xff1a;上面写到主机密钥验证失败&#xff0c;无法从远程仓库拉取。说明我们需要生成一个新的密…

基于JAVA SSM框架和jsp的学生宿舍管理系统

计算机信息技术和当前办公的信息化、自动化、网络化极大地改变了高校、企事业单位的信息管理方式&#xff0c;高效、快速、准确的信息管理已成为各行业现代管理的重要手段。目前宿舍管理人员普遍年龄偏大&#xff0c;使用笔录工作量大&#xff0c;管理难度大&#xff0c;利用学…

如何安装官网最新版Android Studio

1、进入android studio官网&#xff0c;点击下载。 2、下滑查看协议&#xff0c;勾选同意按钮&#xff0c;点击下载。 3、打开安装程序&#xff0c;点击Next。 4、选择虚拟机&#xff0c;点击Next。 5、选择安装路径&#xff0c;点击Next。 6、点击Install。 5、等待安装…

Kafka学习---2、kafka生产者、异步和同步发送API、分区、生产经验

1、kafka生产者 1.1 生产者消息发送流程 1.1.1 发送原理 在消息发生的过程中&#xff0c;设计到了两个线程——main线程和Sender线程。在main线程中创建了一个双端队列RecordAccumulator。main线程将消息发给RecordAccumulator&#xff0c;Sender线程不断从RecordAccumulato…