Qt之基础体系

基础体系

  • 信号与槽
  • 字符串类应用
    • 1. 操作字符串
    • 2. 查询字符串
  • QMap & QHash & QVector
    • QMap
    • QHash
    • QVector
  • QVariant

信号与槽

1、信号(signal):所谓信号槽(观察者模式),信号本质是事件。信号展现方式就是函数。当某一个事件发生之后,则发出一个信号(signal)。

2、槽(slot):就是对信号响应的函数,槽就是一个函数。 槽函数与普通函数区别:槽函数可以与一个信号关联,当信号被发射的时候,关联的槽函数被自动执行处理。信号与槽关联是使用Q0bject:connect)函数进行实现。

3、信号函数只需要声明(不需要定义(实现)),而槽函数需要定义(实现)信号和槽机制底层是通过函数之间进行相互调用实现的。每个信号都可以用函数来表示,称为信号函数;每个槽也可以用函数表示,称为槽函数。槽函数可以使用 public slots/protected slots/private slots 修饰。signals和 slots 是 Qt 开发当中在 C++语言基础之上扩展的关键词,专门用于指明信号函数和槽函数。

4、在Qt中,connect函数是信号与槽(Signals and Slots)机制的核心,它用于建立对象之间的通信。当某个特定事件发生时(比如用户点击了一个按钮),一个对象会发出一个信号(Signal)。这个信号可以被其他对象的一个槽(Slot)函数接收并处理,从而实现对象之间的通信和解耦。

5、信号与槽机制效率:1增强对象的之间通信的灵活性,但是也会损失一些性能。通过传递一个信号来调用槽函数将会比直接调用非虚函数运行速度慢,主要原因多线程的时候,信号可能需要排队等待;编组/解组传递的参数;安全地遍历所有的关联;需要定位接收信号的对象。

connect(sender, &SenderClass::signalName, receiver, &ReceiverClass::slotName);

sender:发出信号的对象指针。
&SenderClass::signalName:指向发送者类中信号的指针。
receiver:接收信号的对象指针。
&ReceiverClass::slotName:指向接收者类中槽函数的指针。

示例:

    // 增加标签lab1 = new QLabel(this);lab1->setText("请输入球的半径:");// 标签2lab2 = new QLabel(this);// 输入框lEdit = new QLineEdit(this);// 按钮计算pbt = new QPushButton(this);pbt->setText("计算圆球体积");// 布局管理器QGridLayout *gl = new QGridLayout(this);gl->addWidget(lab1, 0, 0);gl->addWidget(lab2, 1, 0);gl->addWidget(lEdit, 0, 1);gl->addWidget(pbt, 1, 1);

connect的常见用法:

    // 关联槽函数// 按钮点击/释放connect(pbt, &QPushButton::clicked, this, &Widget::CalcBallVolume);// 文本中的变化connect(lEdit, SIGNAL(textChanged(QString)), this, SLOT(CalcBallVolume()));connect(lEdit, &QLineEdit::textChanged, this, &Widget::CalcBallVolume);

字符串类应用

1. 操作字符串

QString提供一个二元的“+”操作符,主要用于组合两个字符串。QStringstr1= "Hello world"传递给QString一个const char*类型的ASCII字符串“Hello world”,它被解释为一个典型的以“\0”结尾的C类型字符串。
QString::append()函数具备与“+=”操作符同样的功能,直接在一个字符串末尾添加另一个字符串。

    // +QString str1 = "hello";str1 += " world!";qDebug() << str1;str1.append("!");

QString::sprintf 函数是 Qt 框架中 QString 类的一个成员函数,它提供了一种将格式化的数据插入到字符串中的方式。这个函数与 C/C++ 标准库中的 sprintf 函数在功能上类似,但 QString::sprintf 是专为 QString 设计的,因此它完全支持 Unicode 编码,可以处理各种语言的文本。

QString str;  
str.sprintf("%s was born in %d.", "John", 1990);  
// str 现在是 "John was born in 1990."

QString::arg 是 Qt 框架中 QString 类的一个非常有用的成员函数,它允许开发者将变量或值动态地插入到字符串模板中,从而构建出包含动态内容的字符串。这个函数非常灵活,支持多种数据类型,包括整数、浮点数、字符串等,并且允许自定义格式化选项,如字段宽度、基数(进制)和填充字符。

QString str = QString("%1 %2 %3").arg("Hello").arg("world").arg("!");  
// 输出: Hello world !

当需要插入多个参数时,可以连续调用 arg 函数,参数的替换顺序是按照 %1、%2、%3…的顺序进行的。

QString::insert 是 Qt 框架中 QString 类的一个成员函数,它允许在字符串的指定位置插入另一个字符串。这个函数提供了一种灵活的方式来修改字符串的内容,而不需要重新创建整个字符串。

QString &QString::insert(int position, const QString &str)

position:要插入新字符串的位置索引。索引从 0 开始,即字符串的第一个字符位于索引 0 处。
str:要插入的字符串。
该函数会修改调用它的 QString 对象,将 str 插入到 position 指定的位置,并返回对修改后的字符串的引用。

QString str = "Hello";  
str.insert(5, " World"); // 在索引 5 的位置插入 " World"  
// 现在 str 的值为 "Hello World"

在这个例子中," World" 被插入到 “Hello” 的末尾(因为索引 5 实际上是 “Hello” 字符串的末尾之后的位置)。如果 position 的值超出了原字符串的长度,则 str 会被添加到原字符串的末尾.

2. 查询字符串

QString::startsWith 是 Qt 框架中 QString 类的一个成员函数,用于判断一个字符串是否以指定的前缀开头。这个函数非常有用,特别是在处理字符串匹配和条件判断时。

bool QString::startsWith(const QString &str, Qt::CaseSensitivity cs = Qt::CaseSensitive) const

str:要检查的前缀字符串。
cs:一个枚举值,指定比较时是否区分大小写。默认值为 Qt::CaseSensitive(区分大小写),也可以设置为 Qt::CaseInsensitive(不区分大小写)。

返回值:如果字符串以指定的前缀开头,则返回 true;否则返回 false。

QString str = "Hello, world!";  
bool result1 = str.startsWith("Hello", Qt::CaseSensitive); // 返回 true  
bool result2 = str.startsWith("hello", Qt::CaseSensitive); // 返回 false  
bool result3 = str.startsWith("hello", Qt::CaseInsensitive); // 返回 true

QString::contains 用于判断一个字符串是否包含另一个指定的子串。这个函数在处理字符串匹配、搜索和条件判断时非常有用。

bool QString::contains(const QString &str, Qt::CaseSensitivity cs = Qt::CaseSensitive) const

str:要查找的子串。
cs:一个枚举值,指定搜索时是否区分大小写。默认值为 Qt::CaseSensitive(区分大小写),也可以设置为 Qt::CaseInsensitive(不区分大小写)。
返回值:如果字符串中包含与 str 相等的子串(根据 cs 参数确定大小写敏感性),则返回 true;否则返回 false。

QString str = "Hello, World!";  
QString sub = "World";  
bool result1 = str.contains(sub); // 返回 true,区分大小写  
bool result2 = str.contains("world", Qt::CaseInsensitive); // 返回 true,不区分大小写  
bool result3 = str.contains("Qt"); // 返回 false

QString::compare 是用于比较两个字符串。这个函数可以按照字典序对字符串进行比较,并返回一个整数来表示比较的结果。

int QString::compare(const QString &other, Qt::CaseSensitivity cs = Qt::CaseSensitive) const

other:要与之比较的字符串。
cs:一个枚举值,指定比较时是否区分大小写。默认值为 Qt::CaseSensitive(区分大小写),也可以设置为 Qt::CaseInsensitive(不区分大小写)。
返回值:
如果两个字符串相等(根据 cs 参数确定大小写敏感性),则返回 0。
如果调用字符串(即调用 compare 函数的字符串)在字典序上小于 other 字符串,则返回一个小于 0 的值。
如果调用字符串在字典序上大于 other 字符串,则返回一个大于 0 的值。

QString str1 = "Hello";  
QString str2 = "hello";  
QString str3 = "World";  int result1 = str1.compare(str2, Qt::CaseSensitive); // 返回大于0的值,因为区分大小写  
int result2 = str1.compare(str2, Qt::CaseInsensitive); // 返回0,因为不区分大小写  
int result3 = str1.compare(str3); // 返回小于0的值,因为"Hello"在字典序上小于"World"

QMap & QHash & QVector

QMap

QMap是Qt框架中的一个关联容器类,用于存储键值对(key-value pairs)并提供基于键的快速查找功能。
基本特性
模板类:QMap是模板类,可以存储任意类型的数据作为键和值。
红黑树实现:QMap基于红黑树实现,因此查找、插入和删除操作都具有O(log n)的时间复杂度,保证了高效的性能。
自动排序:QMap可以自动对键进行排序,并且支持自定义排序函数。默认情况下,键是按照升序排序的。
存储多个值:QMap支持一个键对应多个值,这可以通过insertMulti方法实现,或者使用QMultiMap类。
迭代器支持:QMap支持迭代器,可以方便地遍历所有元素。Qt提供了Java风格的迭代器(QMapIterator和QMutableMapIterator)和STL风格的迭代器(QMap::const_iterator和QMap::iterator)。
二、使用方法

实例化QMap对象:
QMap<QString, int> map;
插入数据:
使用operator[]:map["math"] = 100;
使用insert方法:map.insert("English", 98);
使用insertMulti方法插入多个值(针对同一键):
map.insertMulti("Math", 100);  
map.insertMulti("Math", 150);
查找数据:
使用value方法通过键查找对应的值:int value = map.value("Math"); // 返回与"Math"键关联的最后一个插入的值
使用values方法获取与特定键关联的所有值(如果使用了insertMulti):QList<int> values = map.values("Math");
遍历数据:
使用Java风格的迭代器:QMapIterator<QString, int> iterator(map);  
while (iterator.hasNext()) {  iterator.next();  qDebug() << iterator.key() << ":" << iterator.value();  
}
使用STL风格的迭代器:
for (QMap<QString, int>::const_iterator it = map.constBegin(); it != map.constEnd(); ++it) {  qDebug() << it.key() << ": " << it.value();  
}
删除数据:
使用remove方法删除具有指定键的项:map.remove("math");
使用clear方法清除QMap中的所有项:map.clear();
检查键是否存在:
使用contains方法检查QMap中是否包含某个键:bool isOk = map.contains("Math");

注意事项
QMap的键类型必须提供operator<()来指定一个全序,以便QMap能够对其进行排序。
当使用QMap时,如果键类型没有提供operator<(),但提供了比较函数或可以自定义比较函数,也可以通过QMap的构造函数或qSort函数等方式来指定排序规则。
在使用QMap时,如果只需要存储一个键对应一个值的映射关系,并且不关心键的排序,可以考虑使用QHash,因为QHash在平均情况下具有更快的查找速度。

QHash

QHash是Qt框架中的一个基于哈希表的模板类,用于存储键值对,并提供了快速的查找、插入和删除操作。
基本特性
数据结构:QHash基于哈希表数据结构,实现了常数时间复杂度的查找、插入和删除操作(平均情况下为O(1),最坏情况下为O(n))。
键值对存储:QHash存储的是键值对,键和值可以是任意Qt支持的数据类型(包括自定义的类型),前提是键必须支持哈希函数和比较操作。
自动调整:QHash会根据元素的数量自动调整内部存储的大小,以保持高效的操作。
迭代器接口:QHash提供了迭代器接口,可以方便地遍历所有存储的键值对。
无序性:QHash存储的元素是无序的,即不保证元素的顺序与插入顺序一致。

主要操作

创建和初始化
创建一个空的QHash:QHash<KeyType, ValueType> hash;
使用初始值创建QHash:QHash<KeyType, ValueType> hash = {{key1, value1}, {key2, value2}, ...};
插入元素
使用insert()函数:hash.insert(key, value);
使用下标操作符(如果键已存在,则替换其值):hash[key] = value;
删除元素
使用remove()函数:hash.remove(key);
使用迭代器(如果需要):hash.erase(iterator);
查找元素
使用contains()函数检查是否包含特定键:bool contains = hash.contains(key);
使用value()函数获取键对应的值(如果不存在,则返回默认值):ValueType value = hash.value(key, defaultValue);
遍历哈希表
使用范围循环遍历:for (auto key : hash.keys()) { qDebug() << key << ":" << hash[key]; }
使用迭代器遍历:QHash<KeyType, ValueType>::const_iterator it; for (it = hash.constBegin(); it != hash.constEnd(); ++it) { qDebug() << it.key() << ":" << it.value(); }
其他操作
获取哈希表的大小:int size = hash.size();
检查哈希表是否为空:bool isEmpty = hash.isEmpty();
获取所有的键和值:QList<KeyType> keys = hash.keys(); QList<ValueType> values = hash.values();

自定义类型支持
如果要在QHash中使用自定义类型作为键,需要提供该类型的qHash()函数和operator==()操作符。这样,QHash才能正确地计算哈希值和比较键的相等性。

线程安全性
QHash不是线程安全的。如果在多线程环境中使用,需要自行加锁以保证线程安全。可以使用Qt提供的互斥锁(QMutex)、读写锁(QReadWriteLock)等同步机制。

高级用法
insertMulti():允许插入多个具有相同键的值(但QHash本身不直接支持此功能,通常使用QMultiHash)。
自定义哈希函数和比较函数:对于复杂的自定义类型,可以通过特化qHash()函数和operator==()操作符来支持。
容量管理:可以使用reserve()函数预分配哈希表的容量,以减少后续插入操作时的内存分配次数。

QVector

QVector是Qt框架中提供的一个动态数组类,用于存储和操作动态大小的对象。它类似于C++标准库中的std::vector,但提供了更多的功能和便利性。以下是对QVector的详细介绍:

基本特性
动态大小:QVector可以根据需要自动调整大小,无需手动管理内存。
高效访问:QVector提供了快速的随机访问,可以通过索引直接访问元素。
插入和删除:QVector支持在任意位置插入和删除元素,自动调整数组大小。
自动复制:QVector在插入和复制元素时会自动进行深拷贝,确保数据的独立性。
内存优化:QVector会根据需要自动分配和释放内存,减少内存占用。

使用场景
QVector可以用于存储和管理一组数据,如数字、字符串、自定义对象等。
它也可以作为其他容器类的基础,如栈、队列、堆等。
在图形界面编程中,QVector可以用于存储和管理图形界面元素,如控件、图像等。
QVector还可以用于实现各种算法,如排序、查找、过滤等。

定义与初始化
使用QVector前,需要包含其头文件#include 。QVector可以通过多种方式进行定义和初始化:
使用默认构造函数,创建一个空的QVector对象。
使用带有初始大小参数的构造函数,创建一个指定大小的QVector对象,元素初始化为默认值。
使用带有初始值和大小参数的构造函数,创建一个指定大小并初始化所有元素的QVector对象。
使用拷贝构造函数,创建一个与已有QVector相同的新QVector对象。
使用列表初始化语法,创建一个包含指定元素的QVector对象。

主要操作
QVector提供了一系列方便的操作函数,可用于对元素进行增删改查等操作:

添加元素:可以使用append()、push_back()等方法在QVector尾部添加元素,也可以使用prepend()、push_front()等方法在头部添加元素。
插入元素:可以使用insert()方法在QVector的任意位置插入元素。
删除元素:可以使用remove()方法删除指定位置的元素,或者使用pop_back()、pop_front()方法删除最后一个或第一个元素。
访问元素:可以使用at()、operator[]等方法通过索引访问元素。
替换元素:可以使用replace()方法替换QVector中指定下标的元素。
查找元素:可以使用indexOf()方法查找元素在QVector中的位置。

容量与迭代器
容量:QVector的容量是指其内部可以存储的元素的数量,这不一定等于其当前存储的元素数量。可以使用capacity()方法获取QVector的容量,使用reserve()方法预留足够的空间。
迭代器:QVector提供了STL风格的迭代器,可以使用begin()和end()方法获取指向第一个元素和最后一个元素之后位置的迭代器。

注意事项
在使用QVector时,需要注意其自动内存管理的特性,避免内存泄漏等问题。
QVector在插入和删除元素时可能会重新分配内存,这可能会影响性能。因此,在需要频繁进行插入和删除操作的场景下,需要谨慎使用QVector。

QVariant

QVariant是Qt框架中一个非常强大的类,它提供了一种通用的方式来存储和处理各种不同类型的数据。

基本概述
定义:QVariant是Qt中用于处理各种数据类型的通用类。它可以存储几乎任何类型的数据,包括基本数据类型(如整数、浮点数、布尔值等)、字符串、自定义数据类型、以及Qt的各种对象类型。
功能:QVariant在Qt中被广泛用于处理不同的数据类型,支持自动类型转换,提供了类型安全的操作,支持跨线程操作,并且可以用于信号和槽、属性系统、数据模型等多种场景。

主要特性
通用性:QVariant可以存储各种不同的数据类型,包括基本数据类型、对象类型、自定义类型等。
自动类型转换:QVariant具有自动类型转换的功能,可以在需要时将存储的数据自动转换为目标类型。
类型安全:QVariant提供了类型安全的接口,可以在运行时检查数据类型,并在类型不匹配时进行错误处理。
跨线程支持:QVariant支持在不同线程之间安全地传递和操作数据,适合多线程应用程序的开发。
容器支持:QVariant可以作为QMap和QList等容器的数据类型,支持复杂的数据结构。

支持的数据类型
QVariant支持多种数据类型,包括但不限于:
基本数据类型:int、double、bool等。
字符串:QString。
日期和时间:QDate、QTime、QDateTime。
颜色和图形:QColor、QImage、QPixmap等。
字节数组:QByteArray。
容器类型:QList、QMap、QVariantList、QVariantMap等。
自定义类型:通过QDataStream的插入和提取操作符实现存储和恢复。

使用方法
QVariant的使用非常灵活,以下是一些基本的使用方法:
存储数据:可以使用QVariant的构造函数或setValue()方法存储数据。
获取数据:可以使用toXXX()系列方法(如toInt()、toDouble()、toString()等)将QVariant中的数据转换为特定类型。
类型检查:可以使用type()方法检查QVariant当前存储的数据类型,或使用canConvert()方法检查是否可以转换为特定类型。

注意事项
性能问题:QVariant不同于其他基础数据类型,其存储和转换操作可能涉及一定的性能开销。因此,在性能要求较高的场景下,应谨慎使用QVariant。
类型安全:虽然QVariant提供了类型安全的接口,但在进行类型转换时仍需注意类型匹配问题。如果转换类型与目标类型不匹配,可能会引发运行时错误。
内存占用:QVariant的存储需要占用一定的内存空间。因此,在存储大量数据或复杂数据结构时,应关注内存使用情况。

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

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

相关文章

webpack配置代理请求

在 Webpack 中&#xff0c;可以通过配置devServer中的proxy选项来设置代理请求&#xff0c;以解决开发环境中的跨域问题或实现特定的请求转发逻辑。以下是一个常见的 Webpack 配置示例&#xff0c;展示了如何设置代理&#xff1a; module.exports {// 其他配置项...devServer…

Java异常抛出与处理方法

在Java编程中&#xff0c;异常处理是一个非常重要的部分。通过正确的异常处理&#xff0c;我们可以提高程序的健壮性和可靠性&#xff0c;避免程序在运行过程中出现意外的崩溃。本文将详细讲述Java异常的抛出与处理方法&#xff0c;并通过示例代码进行说明。 一、Java异常的分…

11 网络编程、反射

文章目录 网络编程1、网络的相关概念2、InetAddress 类3、Socket4、TCP 网络通信编程5、UDP 网络通信编程 反射1、反射机制2、Class 类3、类加载4、通过反射获取类的结构信息5、通过反射创建对象6、通过反射访问类中的成员 网络编程 1、网络的相关概念 网络通信 网络 ip 地…

安全防御:智能选路

目录 一、智能选路 1.1 就近选路 1.2 策略路由 1.3 虚拟系统---VRF 二、全局选路策略 1&#xff0c;基于链路带宽进行负载分担 2&#xff0c;基于链路质量进行负载分担 3&#xff0c;基于链路权重的负载分担 4&#xff0c;根据链路优先级的主备备份 DNS透明代理 一、…

在 Ubuntu上安装 Docker

支持的平台 Docker 提供来自以下 Linux 发行版的软件包 和架构&#xff1a;.deb.rpm 平台x86_64 / amd64Ubuntu的✅Debian 的✅红帽企业 Linux &#xff08;RHEL&#xff09;✅软呢帽✅ Docker 在上述发行版的当前 LTS 版本和最新版本上支持 Docker Desktop。随着新版本的推…

Codeforces Round 895 (Div. 3)(A~G)

A. Two Vessels Problem - A - Codeforces 要我们找到最少操作多少次&#xff0c;a和b内的水一样多&#xff0c;从a拿出i克放到b中&#xff0c;之间的差距减少2i&#xff0c;数据范围不大&#xff0c;循环解决即可。 #include<iostream> #include<algorithm> #in…

推荐算法——MRR

定义&#xff1a; MRR计算的是第一个正确答案的排名的倒数&#xff0c;并对所有查询取平均值。它衡量了模型在排序结果中快速找到正确答案的能力。 其中&#xff1a; Q 是查询的总数。ranki​ 是第 i 个查询中第一个正确答案的排名&#xff08;位置&#xff09;。如果第一个正…

Django定时任务框架django-apscheduler的使用

1.安装库 pip install django-apscheduler 2.添加 install_app django_apscheduler 3.在app下添加一个task.py文件&#xff0c;用来实现具体的定时任务 task.pydef my_scheduled_job():print("这个任务每3秒执行一次", time.time()) 4.在app下创建一个manag…

我在哪里可以找到Vim速查表备忘单?

以下是一些适合初学者和高级用户的Vim速查表推荐&#xff1a; aral的Vim速查表 这是一个空间感强且易于理解的速查表&#xff0c;帮助你理解每个命令将跳转到的位置。aral的Vim速查表 Vim速查表 如果你需要一个全面且用户友好的速查表&#xff0c;可以访问Vim速查表。这个资源…

Redis 教程:从入门到入坑

目录 1. Redis 安装与启动1.1. 安装 Redis1.1.1. 在Linux上安装1.1.2. 在Windows上安装 1.2. 启动 Redis1.2.1. 在Linux上启动1.2.2. 在Windows上启动 1.3. 连接Redis1.3.1. 连接本地Redis1.3.2. 连接远程Redis1.3.2.1. 服务器开放端口1.3.2.2. 关闭防火墙1.3.2.3. 修改配置文件…

【QT开发(19)】2023-QT 5.14.2实现Android开发,使用新版SDK,试图支持 emulator -avd 虚拟机

之前的博客【QT开发&#xff08;17&#xff09;】2023-QT 5.14.2实现Android开发&#xff0c;SDK是24.x版本的&#xff0c;虚拟机是32位的&#xff0c;但是现在虚拟机是64位的了&#xff0c;需要升级SDK匹配虚拟机 文章目录 最后的效果1.1 下载最新版 SDK tools (仅限命令行工…

java学习--面向对象三大特征--继承

子类也可以有子类&#xff0c;ed就是子类的子类&#xff0c;也可以是a的子类 package com.extend_test01;public class Extends {public static void main(String[] args) {Pupil pupil new Pupil();pupil.setName("xiao");pupil.setScore(60);pupil.tesing();Syst…

【华为机考真题】字符串压缩

这里写自定义目录标题 部分通过&#xff0c;请问该咋改 部分通过&#xff0c;请问该咋改 给定一段英文句子和一个英文单词列表。英文句子包含英文单词和标点符号&#xff0c; 其中&#xff1a; 1&#xff09;英文单词只包含[a-zA-Z]范围内的字符 2&#xff09;标点符号包括逗号…

7月17日学习打卡,数组

hello大家好呀&#xff0c;本博客目的在于记录暑假学习打卡&#xff0c;后续会整理成一个专栏&#xff0c;主要打算在暑假学习完数据结构&#xff0c;因此会发一些相关的数据结构实现的博客和一些刷的题&#xff0c;个人学习使用&#xff0c;也希望大家多多支持&#xff0c;有不…

线性回归中的平方损失和正规方程

损失函数 损失函数是用来衡量机器学习模型性能的一个函数。它通过计算模型的预测值与真实值之间的误差&#xff0c;用一个实数来表示这种误差。误差越小&#xff0c;说明模型的性能越好&#xff0c;预测越准确。在确定损失函数之后&#xff0c;通过优化算法求解损失函数的极小值…

初学者如何通过建立个人博客盈利

建立个人博客不仅能让你在网上表达自己&#xff0c;还能与他人建立联系。通过博客&#xff0c;可以创建自己的空间&#xff0c;分享想法和故事&#xff0c;并与有相似兴趣和经历的人交流。 本文将向你展示如何通过建立个人博客来实现盈利。你将学习如何选择博客主题、挑选合适…

阿里云短信PHP集成api类

无需安装sdk扩展包&#xff0c;直接引入类即可使用 V3版本请求体&签名机制:自研请求体和签名机制 - 阿里云SDK - 阿里云 模版内容&#xff1a; <?phpnamespace common\components;use common\constant\UserConst; use common\models\bee\SmsReferer; use common\mode…

Python成像质谱流式细胞术病理生理学

&#x1f3af;要点 &#x1f3af;急性呼吸窘迫综合征病理生理学 | &#x1f3af;获取高度多重空间分辨数据 | &#x1f3af;临床注释病理学景观 | &#x1f3af;使用医学院病理学系提供的组织样本 | &#x1f3af;设计抗体组捕获不同免疫和基质区室 | &#x1f3af;获取适合代…

EXCEL的自定义功能

一、Excel文件获取 OFFICE中导入文本文件&#xff0c;CSV&#xff08;分隔符通常是逗号&#xff09;和TXT&#xff08;分隔符通常是Tab键&#xff0c;可以用记事本打开查看分隔符&#xff09;进入单元格&#xff0c;数据——获取外部数据——自文本。 WPS中数据——获取数据——…

ASP 快速参考

ASP 快速参考 概述 ASP&#xff08;Active Server Pages&#xff09;是一种由微软开发的服务器端脚本环境&#xff0c;用于动态网页设计和开发。它允许开发者创建和运行动态交互性网页&#xff0c;如访问数据库、发送电子邮件等。ASP页面通常以.asp为文件扩展名&#xff0c;并…