QT基础初学

目录

1.什么是QT

2.环境搭建

QT SDK的下载

QT的使用

QT构建项目

快捷指令

QT的简单编写

 对象树

编码问题

组件

初识信号槽

窗口的释放

窗口坐标体系


1.什么是QT

QT 是一个跨平台的 C++ 图形用户界面库,支持多个系统,用于开发具有图形界面的应用程序。它由挪威公司 TrollTech(现为 Digia 的一部分)出品,后来更名为 The Qt Company。QT 不仅仅是一个图形用户界面库,它还包含用于网络通信、线程、数据库、正则表达式处理、XML 处理、JSON、国际化、音频和视频处理等的库。

对于GUI的开发方式,QT只是其中一种,由于GUI也大多应用在客户端,而不是服务器,因此主要是在windows下环境的开发,当然也有许多GUI的开放方式:

基于c/c++的:

1.首先就是比较古老的,windows提供的原生API, Windows API,开发较为繁琐。

2.利用面向对象思想封装成类--MFC就是其中之一,由微软公司提供的GUI开发库。

3.同时代也诞生出了QT,也是利用了面向对象的思想,但是QT一直在推成出新,一直在更新,但是MFC已经很久不更新了。

后来微软自己又推出了新的体系例如c# (.net)下的 Windows Forms,之后又升级成了WPF,UWP.

2.环境搭建

Qt ⽀持多种开发⼯具,其中⽐较常⽤的开发⼯具有:Qt Creator、Visual Studio、Eclipse,

无论是哪一种开发工具,我们都需要准备三件事:

1.下载c/c++的编译器(gcc,cl.exe)。

2.QT SDK(qt软件开发工具包的安装),不过一般SDK会内置一个C++的编译器(mingw下的gcc)。

3.集成开发环境VS (比较重量级,功能更多,但需要额外配置,初学不建议),QTcreater(有些许bug,不过上手方便好用,适合初学),Eclipse等(生态有限)。

不过现在对于这三个东西,你安装QTcreator就已经足够了。

QT SDK的下载

首先我们去官方下载qt sdk,官网点击这里:Index of /archive/qt,选择一个较新的版本进行安装例如5.14进入文件夹内,2.6G的这个大小的就是我们qt的sdk,选择合适的系统安装。

国外网站下载比较慢,所以下载是比较慢的。安装之后就点击一路next基本上就可以了。

其中选择安装的组件,windos下我们就用Mingw--与QT creater就可以,如果你使用VS进行开发,那么可以安装Msvc.最后配置一下环境变量,后面的操作就比较方便。

打开文件会发现关于QT的又许多个文件,其中QT Assistance是官方文档,QT designer是支持拖拽式的图形界面开发,linguist QT语言家,支持国际化。我们主要使用的是QT creater集成开发环境。

QT的使用

使用方法和VS类似,我们首先创建项目,在项目里可以看见左侧有许多,开发GUI我们就使用application,选择了左边,右边也有许多开发选项,选择wigets applicatiion(图形化界面模板)。

此时还要进行构建项目的配置,第一个选择路径,其次还有配置构建工具这里就是用qmake,这也是老牌的实用的功能工具了。

之后就是关于文件的设置。

首先使用QT创建项目会创建一些代码,这些代码会包含一个类,而这里的Base class就是选择该类的父类,包括有三个类(QMianWindow  完整的应用程序窗口,Qwidgets表示一个控件,即窗口上的一个部件  Qdialog表示一个对话框的开发)。当前学习我们就使用第二个Qwidgets即可。

然后选择翻译,这个我们不用关注,之后就是构建套件,选择哪一个编译器,如果你之前电脑还安装了VS这样的,你会发现,这里有许多编译器,这里我们就使用当前的MingW即可。最后汇总选择NULL即可。之后就为我们生成了整个项目(包括头文件,源文件,form文件等)。

对于左下角我们可以进行运行调试。构建的项目中的文件,以及调用的类等QT creator都会帮我们创建好.

QT构建项目

简单的helloworld标签的编写,两种方式实现:

第一种方式,直接通过图形化组件的拖拽实现,双击widget.ui进入面板设计,选择Display widget中的lable标签,此时QT Deigner右上角中会出现一个树形的你的组件,此时的ui文件会多出一部分代码代表这个组件,进一步的qmake在编译项目的时候,基于该部分生成一段c++代码。

此时我们重新运行就可以看到发生了变化。在我们的项目路径下的buildXXXX这个文件中的ui_widget.h,也就是我们的父类文件,在这里面生成了对应的代码:

第二种方式写代码的方式

首先重新创建一个项目,一般我们在添加组件的代码放在.cpp的父类中的构造函数中

在此时前,我们需要直到每创建了一个组件就需要你去包含该组件名对应的头文件,创建组件时使用堆栈都可以,建议用堆,同时参数为this,指定父对象(因为对象树)。

对象树:QT中时使用对象树将不同组件连接在一起的

由于QT开发的比较早,对于一些基础类型,用那时候的c/c++的感觉都不好,因此QT自己搞了一套轮子,自己重新的将基本数据类型重新封装了支持QT的顺畅开发如(Qstring ,Qlist,Qvector,Qdict...)。不过后期c++发展的比较好,都比较完善了,但QT也不可能把自己的删了,所以其实这两套用法作用其实差不多。

因此开发过程中这两种容器都可以,但QT的一些原生接口使用的是QT自己的类型。

Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);//创建标签对象QLabel * lable=new QLabel(this);//设置文本内容lable->setText("hello world");
}

根据这个简单代码我们基本了解的QT。

快捷指令

Qt Creator 中的快捷键
注释:ctrl + /
运⾏:ctrl + R
编译:ctrl + B
字体缩放:ctrl + ⿏标滑轮
查找:ctrl + F
整⾏移动:ctrl + shift + ⬆/⬇
帮助⽂档:F1
⾃动对⻬:ctrl + i;
同名之间的 .h 和 .cpp 的切换:F4
⽣成函数声明的对应定义: alt + enter
使⽤帮助⽂档
打开帮助⽂档有三种⽅式. 实际编程中使⽤哪种都可以.
1、光标放到要查询的类名/⽅法名上, 直接按 F1
2、Qt Creator 左侧边栏中直接⽤⿏标单击 "帮助" 按钮

QT的简单编写

 对象树

对于以上代码,有的同学可能会有疑问,为什么没有释放,这是因为在创建的时候,我们将它挂到了对象树上,调用了析构释放掉了。

QT通过对象树将各个组件关联起来,以N叉树的结构连接起来,对象树也会将这些组件统一释放掉。例如假想一下,如果我们项目的父类是widget,那么在其他组件创建时,都需要传widget的指针给这些对象连接,此时就是将widgt作为对象树root,其他组件为子节点,即将这些组件添加到主窗口上,当窗口关闭,调用窗口析构时在调用组件析构,而不需要我们手动释放。

其次因为我们是界面开发,因此不能存在窗口还在,但是组件已经被释放掉了,而是当窗口关闭时,统一释放所有组件,随意在栈上创建的,也就存在提前释放的情况。我们可以通过自己创建一个标签类,析构中打印信息,此时再去创建,关闭窗口就会自动调用析构:

#include "mylable.h"
#include<iostream>
myLable::myLable(QWidget * parent):QLabel(parent)
{}
myLable::~myLable()
{std::cout<<" 你好"<<std::endl;
}//widget.cpp的构造
Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);myLable * lable=new myLable(this);lable->setText(" hello world");
}

编码问题

由于QT的控制台默认编码格式是gbk,而QT creator编写代码的格式为utf-8,所以会出现编码不一致的问问题,因此我们可以在高级里修改QT的编码格式且按照当前编码设置为gbk可以解决该问题。除此之外,QT提供了Qstring可以进行编码格式的修改,且也提供了专门打印日志的工具        Qdebug可以用来打印日志。

组件

除了基本父类组件 Qwidget(继承的子类Widget) 一个简单窗口,QMainWindow(MainWindow) 包含菜单栏,工具栏的多个组建的窗口,QDialog(QDialog)--对话框。

剩下的就是与窗口齐平的组件,这些组件一般需要传入父类指针实现组件的绑定其中包括:

初识信号槽

信号槽(Signal-Slot mechanism)是一种在软件开发中常用的设计模式,特别是在Qt框架中,它用于实现对象间的通信和事件处理。以下是关于信号槽的详细解释:

基本概念

  • 信号(Signal):对象发出的一种特定事件,类似于广播,没有特定的接收者。例如,当按钮被点击时,按钮对象会发出一个“clicked”信号。
  • 槽(Slot):用于响应信号的特定函数或方法。槽可以是任何对象的成员函数,也可以是全局函数或静态成员函数。当信号被发出时,与之相关联的槽会被自动调用。

实现原理

  • 解耦:信号和槽机制实现了对象间的解耦,即发送者和接收者之间不需要知道对方的具体实现细节。
  • 连接:通过connect函数,可以将信号和槽进行连接。当信号被发出时,与之连接的槽会被自动调用。
  • 语法和宏:在Qt中,信号和槽通过特定的语法和宏进行声明和连接,例如SIGNAL(signal)SLOT(slot)

特性

  1. 类型安全:需要关联的信号和槽的签名必须是一致的,这保证了类型的安全性。
  2. 松散耦合:信号和槽降低了Qt对象之间的耦合度,使得代码更加灵活和可维护。
  3. 多对多关系:多个信号可以与单个槽进行连接,单个信号也可以与多个槽进行连接。

用途

  • 窗口间通信:在Qt中,信号槽是实现不同窗口间通信的主要方式。
  • 事件处理:当某个事件发生时,通过发出信号并调用相应的槽函数来处理该事件。

示例

以按钮点击事件为例,当按钮被点击时,按钮对象会发出一个“clicked”信号。如果有对象对这个信号感兴趣,它就可以使用connect函数将“clicked”信号与自己的一个槽函数进行连接。当按钮被点击时,“clicked”信号被发出,与之连接的槽函数会被自动调用,从而实现了对按钮点击事件的处理。

优缺点

  • 优点:降低了对象间的耦合度,提高了代码的可维护性和灵活性;实现了类型安全。
  • 缺点:与回调函数相比,信号和槽的运行速度可能稍慢,因为需要遍历信号和槽的关联关系并执行相应的槽函数。

总之,信号槽是一种强大的对象间通信机制,在Qt框架中得到了广泛应用。通过合理地使用信号槽,可以编写出更加灵活、可维护和可扩展的代码。

Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);QPushButton *button=new QPushButton(this);button->setText("按钮");connect(button,&QPushButton::clicked,this,&Widget::HandleClick);
}

例如以上代码在我们创建一个新的按钮组件后,利用信号槽进行了信号的捕捉,这个信号对于组件本事有封装的信号产生函数,当收到该信号,就会去让处理信号的对象的组件做出对应的操作HandleClick--例如我这里是打开一个新的窗口:

如果是使用图形化创建窗口,此时并不需要new一个QPushButton,也不需要放在QWidget中,而是在生成项目的时候,就已经在内部的ui中构建了一个成员变量,可以通过ui进行访问,也不想需要释放。

窗口的释放

由于主窗口关闭时,会自动执行析构函数,而子窗口关闭时,却不会调用析构函数,因此著窗口关闭时调用析构需要我们来设计:

方法一构造添加内置窗口析构函数

直接在构造函数添加如下代码,然后就可以调用子窗口析构函数了。

setAttribute(Qt::WA_DeleteOnClose);

第二种方法是 重写虚函数

当窗口关闭瞬间,会发射一个关闭信号,调用槽函数void closeEvent(QCloseEvent* event),只需要在需要关闭的窗口重写虚函数closeEvent(),在关闭该窗口瞬间,会自动调用该虚函数。该方法不会受其它窗口影响,也即是其它窗口关闭,不会调用这个窗口的closeEvent()虚函数。只会在该窗口类起作用。

void Widget::closeEvent(QCloseEvent *event)
{Q_UNUSED(event);//event->accept();//delete this;qDebug("关闭了窗口");
}

Q_UNUSED()函数在程序中的作用,就如它所代表的英文一样,unused,即无用的意思。即Q_UNUSED()函数在程序中没有实质性的作用,用来避免编译器警告。

第三种方法自定义信号槽

连接close信号到一个自定义槽函数,以便在窗口关闭之前执行特定的操作。接下来我们主要学习QT的信号槽机制。

窗口坐标体系

在计算机中使用的是左手坐标系

当我们创建组件,如果没有设置坐标系的位置,默认是(0,0),可以通过组件的接口move移动组建的位置,单位是像素,例如我们笔记本电脑的显示的像素就是(水平)1920 *1080 (垂直),即1080p。其实就是小灯泡的个数。

槽与信号

说到信号大家肯定不陌生,因为我们在学习Linux时就已经知道了,Linux中是有一个信号机制的,且包含大量的信号,通过发送特定的信号,系统捕捉到信号就回去内核态执行对应的信号处理函数,如果是用户重写了信号处理函数,那么就存在用户态到内核态到用户态的过程。

在QT中为了实现组件之间的通信,也引入了信号机制,虽然两者并没什么关系,但还是具有许多相似性。

对于一个信号就要涉及到三个要素:

信号源-----由哪一个组件发出的。

信号的类型---------这是什么样的信号? 点击按钮信号,关闭窗口信号,移动光标信号,下拉框选择信号.......等等各种组件产生的信号。

信号处理的方式:slot(槽) ------->一个函数

而在QT中就可以使用一个connect函数将一个信号和一个槽关联起来。这有收到该信号就去调用槽函数处理,这个槽函数其实就是一个回调函数。那么对于该信号槽机制比较重要的就是connect了,那我们来看看connect的原型:

第一个参数为一个部件类的指针,表示信号源,第二个参数表示的是信号的类型,第三个信号表示负责信号的组件,第四个参数表示如何处理信号,第五个参数有初始值一般不关注。

对于信号分两种:一种是对象自己本身就已经封装有的,一种是自定义的信号。

像这种载体是的时候有一个这样的信号的图标的就是信号,代表点击的信号

而这种就是槽函数,这是去做对应操作的,例如这里就是去关闭组件。

其次QT规定了在使用connect的时候,参数一是啥组件,参数二的类型就是在这个组件(我的父类也可以)内定义好的信号类型,即信号类型与信号源相匹配。

对于槽函数也分两种:一种的已经内置的,一种是自定义的。

参数三与参数四就分别是处理的组件,以及用来处理信号的槽函数的地址。

问题:为什么参数是char*,而我们传的是函数指针?

实际上这个connect函数声明是以前旧版本的声明,首先两个指针肯定不是同类型的,不能直接转,而现在的版本实际上提供了两个宏Signal和SLOT,这两个宏可以将对应的槽函数与信号函数指针转会为char*,QT5之后对于参数进行了优化,即使用函数模板,使用泛型参数进行转化,不需要写宏。

自定义信号与自定义槽

无论是信号还是槽都是组件的成员函数,所以除了内置的,我们可以自己在类中编写我们需要的成员函数/

自定义槽

例如按钮的点击信号对应处理的槽:

void Widget::HandleClick()
{this->close();//点击按钮,关闭窗口
}

但是在类中声明时需要signal: 或者slot:修饰,在以前时是private/public/protected signals/slots :修饰的,除了这种方式外,我们还可以以图形化界面的方式自定义信号与槽(底层自动代码,但相对比较固定)。

当我们选择后QT会帮我们自动创建好对应的槽函数,生成的槽函数并没有显示connect,QT其实还可以通过函数名字自动连接信号,不需要我们再写connect,每一个组件都有Objectname,如按钮的On_PushButton_clicked()就说明了处理按钮点击事件,但是Objectname一定是按照名字规则

才可以去触发信号槽处理,QMetaObject::connectSlotsByName(Widget),PushButton->setObjectName(),这些函数我们在使用ui构建部件时,编译器会自动帮我们创建的。

所以通过ui创建可以根据命名来自动捕获处理信号,但是手动写的信号,还是需要手动connect,因为我们这里的代码是没有QMetaObject::connectSlotsByName(Widget)来解析函数名的。

自定义信号

除了槽,信号也可以自定义,也是一个成员函数,由private/public/protected signals修饰,但是相对于自定义槽,实际开发中自定义信号不是很用的上,一般外设的信号已经内置有对应的信号函数,因此自定义信号基本上很少用到。

对于自定义信号,是比较特殊的:

1.在QT中,自定义信号只需要声明,在编译过程中编译器会自动生成还信号函数,程序员无法干涉。

2.返回参数类型只能为void,参数有没有都无所谓,支持重载。

3.内置信号会由于你的某个操作,自动发送信号,是封装好的,而自定义信号,不仅需要定义,还要由你来决定在哪里发信号,QT提供了一个关键则emit,用来发送信号。(实际上emit没什么大的作用,我们直接调函数也是可以发送信号的)

注意:先绑定信号与槽之后,在发送信号。

例如:

//先定义一个信号
signals:
void mysignal();
//再定义一个槽
public slots:
void HandleMySignal();
//构造中连接信号于槽
connect(this,&Widget::mysignal,this,&Widget::HandleMySignal);//绑定信号与槽
//发送信号
emit mysignal();//mysignal();void Widget::HandleMySignal()
{this->setWindowTitle("自定义处理信号");
}

除了以上不带参数的信号,也可一定有有参数的信号,此时信号的参数与槽的参数必须保持一致(可以参数一样,也可以信号参数比槽函数多)。这样的设定也是可以去让小于等于槽函数的参数个数的信号都可以来绑定。

//声明
signals:void mysignal(const QString &str);//再定义一个槽
public slots:void HandleMySignal(const QString &str);//会将信号的参数传递给槽//槽的实现
void Widget::HandleMySignal(const QString &str)
{this->setWindowTitle(str);
}
//在点击按钮时发送信号,同时传参数
void Widget::on_pushButton_clicked()
{//发送信号emit mysignal("自定义处理信号");
}

当然内置信号也是有参数的,不过不用我们来传。

最后一点就是在使用信号与槽机制时一定一定要添加上Q_OBJECT这个宏,有了它才能使用信号槽。

connect(this,&Widget::mysignal,this,([this](const QString &str){ this->setWindowTitle(str);}));//不需要声明,定义,直接一次性写


 

因为信号与槽这恶机制,开发者是想要实现除了信号处理的功能,更重要的是实现一对一,一对多,多对多复用信号和槽的这种机制,这种关系与数据库中的关联关系时非常类似的,对于这种关系,QT引出了一张关联表来记录信号与槽之间的关系。

不过这个表格不是真表格,而是connect所绑定的一个个关系。

但是理想很丰满,显示很骨干,实际开发需要中更多的就是一对一,稍微少一点的一对多,多对多基本上是一个伪需求,用不到。

补充:

1.信号与槽的断开:使用disconnect断开信号与槽的连接,用法类似。用的也比较少,一般不会断开,如果是想将之前的连接断开,建立新的连接,不是一对多的绑定,可以使用该函数。

2.槽函数的定义也可以使用lanmda表达式。在c++的时候我们就已经直到,对于函数指针,仿函数,lanmda表达式,这三者之间其实是可以相互替换,三者作用相同,还可以通过包装器作为参数传递。

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

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

相关文章

比较kube-proxy模式:iptables还是IPVS?

kube-proxy是任何 Kubernetes 部署中的关键组件。它的作用是将流向服务&#xff08;通过集群 IP 和节点端口&#xff09;的流量负载均衡到正确的后端pod。kube-proxy可以运行在三种模式之一&#xff0c;每种模式都使用不同的数据平面技术来实现&#xff1a;userspace、iptables…

QT::QNetworkReply类readAll()读取不到数据的可能原因

程序中&#xff0c;当发送请求时&#xff0c;并没有加锁&#xff0c;而是在响应函数中加了锁&#xff0c;导致可能某个请求的finished信号影响到其他请求响应数据的读取 connect(reply,&QNetworkReply::finished,this,&Display::replyFinished);参考这篇文章&#xff…

[LLM]从GPT-4o原理到下一代人机交互技术

一 定义 背景&#xff1a;在推出GPT-4o之前&#xff0c;使用语音模式与ChatGPT交流的延迟较长&#xff0c;无法直接观察语调、多个说话者或背景噪音&#xff0c;且无法输出笑声、歌唱或表达情感。 GPT-4o作为OpenAI推出的一款多模态大型语言模型&#xff0c;代表了这一交互技…

听说京东618裁员?所以日常准备很重要呀

文末有最少必要的面试题&#xff0c;还准备了离线 PDF 版本。 京东也要向市场输送人才了? 这几天看到技术群里不少朋友在讨论京东裁员相关的信息。 我去看了下京东近期的操作&#xff0c;京东内部考勤调整和午休时间缩短&#xff0c;以及强化打卡机制等管理调整&#xff1b;有…

AMEYA360代理 | 村田电子去寄生电感降噪元件(LCT)特点和规格

株式会社村田制作所(以下简称“村田”)开发了行业首款(1)利用负互感(2)、能对从数MHz到1GHz的谐波(3)范围内电源噪声进行抑制的去寄生电感降噪元件“LXLC21系列”(以下简称“本产品”)。只需将1件本产品连接至电源电路中的电容器&#xff0c;即可消除与本产品连接的电容器的ESL…

OpenMv图片预处理

本博客讲述的是获取一张图片首先对图像进行处理,比如畸形矫正,图像滤波等操作。 1.histeq()自适应直方图均衡 # 自适应直方图均衡例子 # # 此示例展示了如何使用自适应直方图均衡来改善图像中的对比度。 #自适应直方图均衡将图像分割成区域,然后均衡这些区域中的直方图,…

ubuntu server版 虚拟机根目录磁盘扩容

之前一直使用桌面版ubuntu,因为项目原因需要拉取的代码太大了且项目比较多选择了体量更小的Ubuntu server版,在使用中发现根目录的磁盘很快就用满了 如上,明明分配的300G但是/dev/mapper/ubuntu--vg-ubuntu--lv 只有98G都用满了 server版本与桌面版不同的是在server版安装的时…

一篇文章搞懂二叉树

文章目录 DP 树叶的度树的度节点的层次节点的祖先节点的子孙双亲节点或父节点 树的表示孩子兄弟表示法双亲表示法树和非树树的应用 二叉树满二叉树完全二叉树推论二叉树的存储以数组的方式以链表的方式堆(Heap)堆的分类大根堆和小根堆的作用 二叉树的遍历DFS和BFS DP 动态规划…

HCIA--DHCP: 动态主机配置协议 (复习)

DHCP: 动态主机配置协议 -- 同一分发管理ip地址 基于UDP 67/68端口工作 网络中存在DHCP的服务器为需要自动生成ip地址的设备分配ip地址&#xff1b;--C/S模型 成为DHCP服务器的条件&#xff1a; 该设备存在接口或网卡连接到所要分发ip地址的广播域内该接口或网卡必须已经配置…

在WHM中如何调整max_upload_size 参数大小

今日我们在搭建新网站时需要调整一下PHP参数max_upload_size 的大小&#xff0c;我们公司使用的Hostease的美国独立服务器产品默认5个IP地址&#xff0c;也购买了cPanel面板&#xff0c;因此联系Hostease的技术支持&#xff0c;寻求帮助了解到如何在WHM中调整PHP参数&#xff0…

全志T527芯片详解【二】:高清图像编解码

硬件模块加持 T527集成了多个图形显示和编解码相关的硬件模块&#xff0c;为高清图像显示、高清视频播放和多路高清摄像头输入提供了强大的硬件基础&#xff1a; ARM Mail-G57 GPU自研显示引擎(Display Engine)去隔行处理单元(De-interIace)2D图像加速单元(Graphic2D)视频编解…

SFOS2:组件介绍

一、前言 在sailfish os application的开发过程中&#xff0c;几乎是困难重重&#xff0c;因为我暂未找到具有完整性、指导性、易懂性的开发文档&#xff0c;特别是组件的使用&#xff0c;现决定将自己的探究结果记录下来。因此&#xff0c;这篇文章只会具有参考价值&#xff0…

链动3+1模式:深度解析与优势探讨

在数字化营销领域&#xff0c;链动模式因其强大的裂变能力和高效的引流机制而备受瞩目。其中&#xff0c;链动21模式一度是商家们的首选&#xff0c;但随着时间的推移&#xff0c;其存在的问题也逐渐显现&#xff1a;预留小号和较低的复购率成为制约其进一步发展的瓶颈。为了解…

map优化多个if

原代码如下&#xff0c;多个按钮的点击操作&#xff0c;其中val是操作的按钮的标志 const operationConst {INSTALLAPP: installApp,STOPAPP: stopApp,HOME: home,CLEAR: clear...... } function moreOperation(val, list) {selectedList list && list.length 0 ?…

最新!2023年台湾10米DEM地形瓦片数据

上次更新谷歌倾斜摄影转换生成OSGB瓦片V1.1版本&#xff0c;使用该版本生产了台北、台中、桃园三个地方的倾斜摄影OSGB数据&#xff0c;在OSGB可视化软件中进行展示&#xff0c;可视化效果和加载效率俱佳。已经很久没更新地形瓦片数据&#xff0c;主要是热点地区的原始数据没有…

算法的时间复杂度(详解)

前言&#xff1a; 算法(Algorithm):就是定义良好的计算过程&#xff0c;他取一个或一组的值为输入&#xff0c;并产生出一个或一组值作为 输出。简单来说算法就是一系列的计算步骤&#xff0c;用来将输入数据转化成输出结果 一、算法效率 1.1 如何衡量一个算法的好坏 如何衡…

3.Linux系统环境搭建

一、虚拟化机&#xff1a;指的是通过虚拟化技术将一台计算机分为多台逻辑计算机。注&#xff1a;虚拟机共用CPU和内存资源。 二、虚拟机用途&#xff1a; 1.搭建学习环境&#xff1a;例如在同一间实验室里&#xff0c;物理机Windows系统&#xff0c;虚拟机可以用Linux系统。 …

汇舟问卷:国外问卷调一天900

大家好&#xff0c;我是汇舟问卷&#xff0c;专注于国外问卷调查互联网项目。夏天已经来临&#xff0c;您是否在三伏天顶着大太阳上班&#xff0c;汗水浸湿了衣襟&#xff0c;却依然要面对繁琐的工作和无尽的压力&#xff1f; 在这个炎热的季节里&#xff0c;我们都渴望找到一…

什么是React?

01 Why React? What is React? I think the one-line description of React on its home page (https://react.dev/) is concise and accurate: “A JavaScript library for building user interfaces.” 我认为React主页(https://react.dev/)上的一行描述既简洁又准确: …

ch3运输层--计算机网络期末复习(持续更新中)

运输层位于网络层之上 运输层协议提供的某些服务受到网络层协议的限制。比如,时限和带宽保证。 运输层也提供自己的特殊服务。比如,可靠数据传输服务,安全性服务。 网络层:两个主机之间的逻辑通信 运输层:两个进程之间的逻辑通信 网络地址:主机的标识(IP地址) 传输地址: …