Qt——升级系列(Level Two):Hello Qt 程序实现、项目文件解析、Qt 编程注意事项

news2024/11/24 11:04:06

Hello Qt 程序实现

  使用“按钮”实现

纯代码方式实现:

a6f9bc08a8a3441bb9844f05a90b6b4f.png

// Widget构造函数的实现
Widget::Widget(QWidget *parent)
    : QWidget(parent)  // 使用父类构造函数初始化QWidget,传入父窗口指针
    , ui(new Ui::Widget)  // 创建Ui::Widget类的实例,并用new动态分配内存
{
    // 调用ui的setupUi函数来初始化界面,传入this指针,即将当前Widget实例与设计的UI绑定
    ui->setupUi(this);
    
    // 创建一个QPushButton对象指针btn
    QPushButton *btn = new QPushButton;
    
    // 设置按钮的文本为"Hello_Qt"
    btn->setText("Hello_Qt");
    
    // 设置按钮的父窗口为当前Widget,这样按钮会自动被管理(包括销毁)
    btn->setParent(this);
}

// Widget析构函数的实现
Widget::~Widget()
{
    // 释放ui指针所指向的内存,防止内存泄漏
    delete ui;
}

 代码结果:df72765f626143ba9bc20df79c8e96af.png

可视化操作实现:

(1)双击:" widget.ui " ⽂件;

aa2a53c24c3f4906ac95c1a8821a5ded.png

(2)拖拽控件⾄ ui 界⾯窗⼝并修改内容;

fbfcd62d85e746bbbe98f2ae4502290b.png

(3)构建并运⾏,效果如下所⽰:

34db1148cc73400e989d6bf8ef6ec516.png

  使用 "标签" 实现

纯代码方式实现:

a6ae1b73f87e42938668d0e45db2655e.png

#include "widget.h"      // 包含自定义Widget类的头文件
#include "ui_widget.h"   // 包含由Qt Designer生成的用户界面类头文件
#include <QLabel>         // 包含QLabel控件的头文件,用于显示文本
#include <QFont>          // 包含QFont类,用于设置字体样式

// Widget类的构造函数
Widget::Widget(QWidget *parent)
    : QWidget(parent)     // 调用基类QWidget的构造函数,传入父窗口指针
    , ui(new Ui::Widget)  // 使用new动态创建Ui::Widget实例
{
    // 初始化由Qt Designer设计的界面
    ui->setupUi(this);

    // 创建一个新的QLabel对象,并将其父窗口设为当前Widget
    QLabel *lab = new QLabel(this);
    
    // 设置QLabel的显示文本为"Hello Qt"
    lab->setText("Hello Qt");

    // 设置窗口固定大小为800x600像素
    setFixedSize(800, 600);

    // 创建QFont对象,设置字体为"华文行楷",字号为64
    QFont font("华文行楷", 64);
    
    // 将创建的字体应用到QLabel上
    lab->setFont(font);

    // 移动QLabel的位置到屏幕上的(0, 300)
    lab->move(0, 300);

    // 设置QLabel的文字颜色为蓝色
    lab->setStyleSheet("color:blue");
}

// Widget类的析构函数
Widget::~Widget()
{
    // 清理由new分配的ui对象,防止内存泄漏
    delete ui;
}

代码结果:9611e95fc9cf46e58a058adb3d1d531d.png

可视化操作实现:

(1)双击:" widget.ui " ⽂件;

(2)拖拽 "标签" ⾄ UI 设计界⾯中,并双击修改标签内容;

2a394d1d75c742e6bdd8144a263e2601.png

(3)实现效果如下图所⽰:

9e5809a3272a49e1be06c92c22def9c9.png

项目文件解析

        在我们创建完一个项目后,Qt Creator 会默认给我们生成以下文件:

90cadda97de94746b18144d3bec94c56.png

  解释 .pro 

42fe24b94af74df8a2a8580c5248455d.png

# Qt项目配置文件 (.pro) 示例

# 添加必需的Qt模块:core和gui。core模块包含基础运行时功能,而gui模块用于构建图形用户界面。
QT       += core gui

# 如果当前使用的Qt版本主版本号大于4,则额外添加widgets模块,因为从Qt5开始,widgets被分离出来作为一个独立模块。
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

# 配置项目以使用C++11标准。这对于利用现代C++特性如auto、lambda表达式等是必要的。
CONFIG += c++11

# 定义宏QT_DEPRECATED_WARNINGS,使得编译器在遇到Qt中已标记为过时的功能时发出警告。
# 这有助于开发者及时迁移代码,避免使用即将不支持的API。
DEFINES += QT_DEPRECATED_WARNINGS

# 注释掉的行展示了如何禁止使用指定版本之前的所有过时API。
# 解除注释并设置期望的版本(如QT_DISABLE_DEPRECATED_BEFORE=0x060000禁用Qt6.0.0前的过时API),
# 可强制编译失败而不是警告,确保代码完全不含旧API。
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # 禁用所有在Qt 6.0.0之前废弃的API

# 指定源文件,项目将从这些文件编译生成可执行代码。
SOURCES += \
    main.cpp \
    widget.cpp

# 指定头文件,这些是源文件中可能引用的声明文件。
HEADERS += \
    widget.h

# 指定UI表单文件,这些是通过Qt Designer设计的界面文件,将被编译为C++代码。
FORMS += \
    widget.ui

# 部署规则设定:
# - 对于QNX系统,目标路径设置为/tmp/${TARGET}/bin
# - 对于其他Unix系统(非Android),目标路径设置为/opt/${TARGET}/bin
# 如果target.path被设置了(即不为空),那么会自动添加一个安装步骤(INSTALLS += target)来安装生成的可执行文件到指定路径。
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target

 .pro ⽂件的写法如下:
1. 注释:从 "#" 开始,到这⼀⾏结束。
2. QT += core gui // Qt 包含的模块 Qt5 包含的模块如下图所⽰:

48cdea165b4a40df8a3a3e495c81b5ec.png

3. greaterThan(QT_MAJOR_VERSION, 4): QT += widgets 这条语句的含义是,如果QT_MAJOR_VERSION ⼤于 4 也就是当前使⽤的 Qt5 及更⾼版本) 需要增加 widgets 模块。如果项⽬仅需⽀持 Qt5 , 也可以直接添加 "QT += widgets" ⼀句。不过为了保持代码兼容 ,最好还是按照 QtCreator ⽣成的语句编写。
4. 指定⽣成的应⽤程序名:TARGET = QtDemo
5. TEMPLATE = app //模板。告诉 qmake 为这个应⽤程序⽣成哪种 makefile。下⾯是可供选择的模板:
⚫ app:建⽴⼀个应⽤程序的 makefile。这是默认值,所以如果模板没有被指定,这个将被使⽤。
⚫ lib :建⽴⼀个库的 makefile。
⚫ vcapp:建⽴⼀个应⽤程序的 VisualStudio 项⽬⽂件。
⚫ vclib: 建⽴⼀个库的 VisualStudio 项⽬⽂件。
⚫ subdirs:这是⼀个特殊的模板,它可以创建⼀个能够进⼊特定⽬录的 makefile 并且为它调⽤make 的 makefile。
6. ⼯程中包含的源⽂件:SOURCES += main.cpp/widget.cpp
7. ⼯程中包含的头⽂件:HEADERS += widget.h
8. ⼯程中包含的资源⽂件:RESOURCES += painter.qrc
9. ⼯程中包含的 "ui" 设计⽂件:FORMS += widget.ui
10. 配置信息:CONFIG += c++11 (使⽤ c++11 的特性) CONFIG ⽤来告诉 qmake 关于应⽤程序的配置信息。

  解释widget.h

5f52a3bfc0094e138a31eda9735019f0.png

// widget.h 文件头部使用预处理器指令防止多次包含
#ifndef WIDGET_H
#define WIDGET_H

// 包含基类 QWidget 的头文件,以便继承
#include <QWidget>

// 使用QT_BEGIN_NAMESPACE和QT_END_NAMESPACE包裹Ui命名空间的声明,
// 以符合Qt的编码规范,避免命名冲突。
QT_BEGIN_NAMESPACE
namespace Ui {
    // 前向声明Ui::Widget类,该类由uic自动生成并用于界面管理
    class Widget;
}
QT_END_NAMESPACE

// 类Widget的声明,它公有继承自QWidget
class Widget : public QWidget
{
    // Q_OBJECT 宏是必须的,用于Qt的信号与槽机制以及国际化支持
    Q_OBJECT

public:
    // 构造函数,接受一个指向父组件的指针,默认为nullptr
    explicit Widget(QWidget *parent = nullptr);
    // 析构函数,清理资源
    ~Widget();

private:
    // 私有成员变量,指向由Qt设计师生成的界面类实例
    Ui::Widget *ui; // 实例化Ui::Widget用于界面控制
};

// 结束条件编译,确保WIDGET_H只被定义一次
#endif // WIDGET_H

        在Qt中,如果要使⽤信号与槽(signal 和 slot)的机制 就必须加⼊ Q_OBJECT 宏;

        Ui::Widget *ui; 这个指针是⽤前⾯声明的 namespace Ui ⾥的 Widget 类定义的,所以指针 ui 是指向可视化设计的界⾯,后⾯要访问界⾯上的组件,都需要通过这个指针 ui 去访问。

  解释 main.cpp

dcb18fe41d4f46f8a450b58f7f53c999.png

// 包含自定义窗口部件类(Widget)的实现文件
#include "widget.h"

// 引入QApplication类,用于管理整个GUI应用程序的控制流程
#include <QApplication>

// 应用程序的主函数
int main(int argc, char *argv[])
{
    // 创建QApplication对象,argc和argv是从命令行传入的参数,
    // 这一行是Qt GUI应用的起点,管理事件循环和提供系统级别的功能
    QApplication a(argc, argv);
    
    // 实例化自定义窗口部件Widget类
    Widget w;
    
    // 调用窗口部件的show()方法,使窗口在屏幕上显示出来
    w.show();
    
    // 启动Qt的事件循环,a.exec()会一直运行直到事件循环结束,
    // 通常当所有窗口关闭时事件循环结束,然后返回 exitCode 给操作系统
    return a.exec();
}

解释:
1. Qt 系统提供的标准类名 声明头⽂件没有 .h 后缀;
2. Qt ⼀个类对应⼀个头⽂件,类名 就是 头⽂件名;
3. QApplication 为应⽤程序类;QApplication a;(a为应⽤程序对象,有且仅有⼀个。)
⚫ QApplication 管理图形⽤⼾界⾯应⽤程序的控制流和主要设置。
⚫ QApplication 是 Qt 的整个后台管理的命脉。它包含主事件循环,在其中来⾃窗⼝系统和其它资源的所有事件处理和调度。它也处理应⽤程序的初始化和结束,并且提供对话管理。
⚫ 对于任何⼀个使⽤ Qt 的图形⽤⼾界⾯应⽤程序,都正好存在⼀个 QApplication 对象,⽽不论这个应⽤程序在同⼀时间内是不是有 0、1、2 或更多个窗⼝。
4. myWidget w; //实例化窗⼝对象
5. w.show(); //调⽤show函数显⽰窗⼝
6. a.exec() :程序进⼊消息循环,等待对⽤⼾输⼊进⾏响应。这⾥ main()把控制权转交给Qt,Qt 完成事件处理⼯作,当应⽤程序退出的时候 exec() 的值就会返回。在 exec() 中,Qt 接受并处理⽤⼾和系统的事件并且把它们传递给适当的窗⼝部件。 

  解释widget.cpp

3343effbc8ca487da3160982fc0d3ff2.png

        widget.cpp ⽂件是类 Widget 的实现代码,所有在窗体上要实现的功能添加在此⽂件中; 

// 包含自定义窗口部件类的头文件
#include "widget.h" 

// 包含由Qt Designer生成的用户界面类头文件,用于界面布局和控件
#include "ui_widget.h"

// Widget类构造函数
Widget::Widget(QWidget *parent)
    : QWidget(parent)  // 使用基类QWidget的构造函数初始化,传入父窗口指针
    , ui(new Ui::Widget)  // 创建Ui::Widget类的实例,并用new动态分配内存
{
    // 调用ui->setupUi(this)来初始化界面,this指针指向当前Widget实例,
    // 这一步会根据.ui文件设置窗口的布局和控件
    ui->setupUi(this);
}

// Widget类析构函数
Widget::~Widget()
{
    // 当Widget实例被销毁时,释放之前动态分配的ui对象的内存
    delete ui;
}

  解释widget.ui

9186df472898499b9ed0db2679e4b32b.png

        widget.ui 是窗体界⾯定义⽂件,是⼀个 XML ⽂件,定义了窗⼝上的所有组件的属性设置、布局,及其信号与槽函数的关联等。⽤ UI 设计器可视化设计的界⾯都由 Qt ⾃动解析,并以 XML ⽂件的形式保存下来。在设计界⾯时,只需在 UI 设计器⾥进⾏可视化设计即可,⽽不⽤管 widget.ui ⽂件是怎么⽣成的。 

ee9a652e2cb54ae8929ead741708970d.png

<!-- XML声明部分,定义了文档的版本为1.0,字符编码为UTF-8 -->
<?xml version="1.0" encoding="UTF-8"?>

<!-- 开始定义Qt用户界面文件,版本号为4.0 -->
<ui version="4.0">

  <!-- 定义用户界面的主类名为Widget -->
  <class>Widget</class>

  <!-- 实际的窗口部件配置开始,这是一个QWidget类型的窗口部件 -->
  <widget class="QWidget" name="Widget">

    <!-- 设置窗口部件的初始几何属性 -->
    <property name="geometry">
      <!-- 使用矩形(rect)来具体定义位置和大小 -->
      <rect>
        <x>0</x> <!-- X轴坐标起始于0 -->
        <y>0</y> <!-- Y轴坐标起始于0 -->
        <width>800</width> <!-- 窗口宽度为800像素 -->
        <height>600</height> <!-- 窗口高度为600像素 -->
      </rect>
    </property>

    <!-- 设置窗口的标题 -->
    <property name="windowTitle">
      <string>Widget</string> <!-- 窗口标题为"Widget" -->
    </property>

  </widget> <!-- QWidget配置结束 -->

  <!-- 资源部分,目前没有定义任何额外资源 -->
  <resources/>

  <!-- 连接部分,目前没有定义任何信号与槽的连接 -->
  <connections/>

</ui> <!-- 用户界面定义结束 -->

Qt 编程注意事项

  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 左侧边栏中直接⽤⿏标单击 "帮助" 按钮:

4c186d9a9a9647aa94d85e59908e3f0e.png

        3、找到 Qt Creator 的安装路径,在 "bin" ⽂件夹下找到 assistant.exe,双击打开;

  认识对象模型(对象树)

        在 Qt 中创建很多对象的时候会提供⼀个 Parent 对象指针,下⾯来解释这个 parent 到底是⼲什么的。

QObject 是以对象树的形式组织起来的。
  • 当创建⼀个 QObject 对象时,会看到 QObject 的构造函数接收⼀个 QObject 指针作为参数,这 个参数就是 parent,也就是⽗对象指针。
  • 这相当于,在创建 QObject 对象时,可以提供⼀个其⽗对象,我们创建的这个 QObject 对象 会⾃动添加到其⽗对象的 children() 列表。
  • 当⽗对象析构的时候,这个列表中的所有对象也会被析构。(注意,这⾥的⽗对象并不是继承意义上的⽗类!)

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

QWidget 是能够在屏幕上显⽰的⼀切组件的⽗类。

  • QWidget 继承⾃ QObject ,因此也继承了这种对象树关系。⼀个孩⼦⾃动地成为⽗组件的⼀个⼦组件。因此,它会显⽰在⽗组件的坐标系统中,被⽗组件的边界剪裁。例如,当⽤⼾关闭⼀个对话框的时候,应⽤程序将其删除,那么,我们希望属于这个对话框的按钮、图标等应该⼀起被删除。事实就是如此,因为这些都是对话框的⼦组件。
  • 当然,我们也可以⾃⼰删除⼦对象,它们会⾃动从其⽗对象列表中删除。⽐如,当我们删除了⼀个⼯具栏时,其所在的主窗⼝会⾃动将该⼯具栏从其⼦对象列表中删除,并且⾃动调整屏幕显⽰。

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

  • 当⼀个 QObject 对象在堆上创建的时候,Qt 会同时为其创建⼀个对象树。不过,对象树中对象的顺序是没有定义的。这意味着,销毁这些对象的顺序也是未定义的。
  • 任何对象树中的 QObject 对象 delete 的时候,如果这个对象有 parent,则⾃动将其从 parent 的children() 列表中删除;如果有孩⼦,则⾃动 delete 每⼀个孩⼦。Qt 保证没有 QObject 会被delete 两次,这是由析构顺序决定的。

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

1f5d813c5849452b887f391a224dcac4.png

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

        但是,如果我们使⽤下⾯的代码:

8af45047911b41d991ea310d87cc7d0e.png

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

        由此我们看到,Qt 的对象树机制虽然在⼀定程度上解决了内存问题,但是也引⼊了⼀些值得注意的事情。这些细节在今后的开发过程中很可能时不时跳出来烦扰⼀下,所以,我们最好从开始就养成良好习惯。

总结:在 Qt 中,尽量在构造的时候就指定 parent 对象,并且⼤胆在堆上创建。

Qt对象树如图:c76b9994712446b399fa4f9faa0c9493.png

  Qt 窗口坐标体系

        坐标体系:以左上⻆为原点(0,0),X向右增加,Y向下增加。

ad4c07a4d618479fb6c3de772f13a797.png

        对于嵌套窗⼝,其坐标是相对于⽗窗⼝来说的。

⽰例:使⽤Qt中的坐标系设置控件的位置;

471739d7d1d44a25a21e5cd6c85d82de.png

 代码结果:

3aca9656636e4d82bbb564fcc6f27849.png

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

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

相关文章

【自定义View】Android圆饼进度条

源码 自定义属性 <?xml version"1.0" encoding"utf-8"?> <resources><declare-styleable name"ArcProgressView"><attr name"android:textSize" /><attr name"bgBorderWidth" format"d…

短视频竖屏:成都鼎茂宏升文化传媒公司

短视频竖屏&#xff1a;重塑视觉体验与社交传播的新潮流 随着移动互联网的迅猛发展和智能手机的普及&#xff0c;短视频已经成为了人们日常生活中不可或缺的一部分。而在短视频的众多形式中&#xff0c;竖屏短视频以其独特的视角和便捷的传播方式&#xff0c;正逐渐崭露头角&a…

Qt绘图(2D)讲解

一、绘图基础 2D 绘图系统如下: 2D 绘图主要是 QPainter、QPaintDevice、QPaintEngine 三个类,主要类的作用(其关系见图示) QPainter(绘制器)是用来执行绘图的操作,用于描述需要绘制的图形,比如需要绘制线、矩形、圆形等。QPaintDevice(绘图设备)是抽象出来的需要绘制的绘…

uni微信小程序editor富文本组件如何插入图片

需求 在editor中插入图片&#xff0c;并对图片进行编辑&#xff0c;简略看一下组件的属性&#xff0c;官网editor 组件 | uni-app官网 解决方案 首先要使用到ready这个属性&#xff0c;然后官网有给代码粘过来&#xff0c;简单解释一下这段代码的意思&#xff08;作用是在不同…

linux实验报告

实验一&#xff1a;Linux操作系统的安装与配置 实验目的&#xff1a; 1.掌握虚拟机技术&#xff1b; 2.掌握Linux的安装步骤&#xff1b; 3.掌握安装过程中的基本配置要求。 4.掌握正确启动Linux的方法&#xff1b; 5.掌握正确退出Linux的方法&#xff1b; 6.熟悉已安装…

Oracle存储过程

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、前置准备1.创建表空间2.创建用户3.赋权 二、存储过程1.创建数据表2.创建存储过程3.执行存储过程4.带参执行5.控制语句 总结 前言 这段时间实习&#xff0c…

.NET AI如何从0开始?

你是否在思考如何利用AI为您公司的产品增加智能方向的业务扩展&#xff1f; 或者你是否有思考过怎么去利用AI减少部分工作量&#xff1f; 如果你有类似于上面的问题&#xff0c;想要学习AI&#xff0c;并且您是一名.NET开发工程师&#xff0c;或您是一名弃暗投明的Java转.NET…

六月的魔力:揭秘2024年加密市场与Reflection的创新与收益

回想过去加密货币市场的沉浮&#xff0c;一年中市场的阶段性牛市大多发生在下半年&#xff0c;六月似乎是一个神奇的时间节点。每年六月一到&#xff0c;加密货币市场仿佛突然被按下启动按钮&#xff0c;沉寂的土狗开始扶苏&#xff0c;经过半年准备的各大项目方开始蠢蠢欲动。…

城市之旅:使用 LLM 和 Elasticsearch 简化地理空间搜索(一)

作者&#xff1a;来自 Elastic Philipp Kahr, Valentin Crettaz 这篇博文的本地部署实践 Jupyter notebook 请详细阅读文章 “城市之旅&#xff1a;使用 LLM 和 Elasticsearch 简化地理空间搜索&#xff08;二&#xff09;”。 探索如何从自然语言提问创建地理空间搜索。在下…

15- Redis 中的 整数集合 数据结构

整数集合是 Set 对象的底层实现之一。当一个 Set 对象只包含整数值元素&#xff0c;并且元素数量不大时&#xff0c;就会使用整数集合这个数据结构作为底层实现。 1. 整数集合结构设计 整数集合本质上是一块连续内存空间&#xff0c;它的结构定义如下&#xff1a; typedef s…

​在 The Sandbox 元宇宙的 CU 超商中寻找Milk币!

CU&#xff08;韩国领先的便利店&#xff09;和 MiL.k&#xff08;基于区块链的忠诚度整合平台&#xff09;合作在 The Sandbox 推出了首款元宇宙游戏&#xff0c;通过独家活动在 Web2 和 Web3 之间建立联系。 在元宇宙中玩转 “Play CU X MiL.k” 体验 通过引人入胜的游戏内容…

uniapp小程序多线程 Worker 实战【2024】

需求 最近遇到个小程序异步解码的需求&#xff0c;采用了WebAssembly&#xff0c;涉及大量的计算。由于小程序的双线程模型只有一个线程处理数据&#xff0c;因此智能寻求其它的解决方案。查看小程序的文档&#xff0c;发现小程序还提供一个异步线程的Worker方案&#xff0c;可…

暗黑系短视频:成都鼎茂宏升文化传媒公司

暗黑系短视频&#xff1a;探索未知的视觉艺术 在短视频盛行的今天&#xff0c;各种风格和主题的作品层出不穷&#xff0c;其中&#xff0c;暗黑系短视频以其独特的魅力和深度&#xff0c;成都鼎茂宏升文化传媒公司吸引了众多观众的关注。这类视频往往带有一种神秘、压抑的氛围…

李良济中医课堂,助力市民健康,传播中医药文化,坚守初心扬国粹!

为了更好地传承并发扬中医文化&#xff0c;传播健康理念&#xff0c;提高民众预防疾病的意识&#xff0c;让广大市民感受到中医药就在我身边。 李良济中医课堂&#xff0c;积极走进老年大学&#xff0c;青年夜校&#xff0c;同时主动加入萌趣中草药的活动等&#xff0c;为市民群…

小程序集arcgis地图显示自定义坐标的功能实现记录!(学习笔记)

最近再做一个新能源回收项目&#xff0c;项目中有个根据回收点坐标数据显示区域内回收点位置&#xff0c;点击图标直接导航到该位置&#xff0c;及分布的需求&#xff0c;研究了一下&#xff0c;实现效果如下&#xff0c;实现起来很简单&#xff0c;代码及效果 回收点位置及分…

在编程Python的时候发生ModuleNotFoundError: No module named distutils报错怎么办

1.先查看Python版本 首先我们先去打开终端就是先widr再输入cmd 然后进去在输入Python -V要注意大小写 我的版本是3.9.7版本但是我使用的PyCharm 是 2021.1.1 x64版本没有办法主动去识别因为这个版太低了你的Python版本很高所以无法识别 2.解决方法 只需要把你的Python现版…

使用手机小程序给证件照换底色

临时遇到一个需求&#xff0c;需要给证件照换底色。原始图像如下 最终需要换成红底的。 本次使用一款小程序&#xff02;泰世茂证件照&#xff02;&#xff0c;打开该小程序&#xff0c;如下图所示 单击开始制作&#xff0c;然后选择二寸红底&#xff0c;如下图所示 然后单击相…

UI 自动化中的分层设计

以前的设计 在过去 UI 自动化测试领域有一个规范的设计模式是 page object 模式。 意思是测试用例不会直接定位页面元素&#xff0c; 而是把每一个页面封装成一个类。 在这个类中封装页面元素。 然后测试用例调用 page 类来操作页面元素完成测试用例。如下图&#xff1a; 以前…

前端面试题(二)答案版

面试形式&#xff1a;线上面试&#xff08;不露脸&#xff09;&#xff1a;时长40分钟 面试评价&#xff1a;由易到难&#xff0c;由细到全&#xff0c;比较不错 面试官&#xff1a;项目经理 面试官提问&#xff08;面试题&#xff09;&#xff1a; 1、聊聊最近写的这个项目…

【Meetup】探索Apache SeaTunnel的二次开发与实战案例

在数据科技快速演进的今天&#xff0c;业务场景的复杂化和数据量的激增&#xff0c;推动了大数据技术的迅速发展&#xff0c;在众多开源大数据处理工具中&#xff0c;Apache SeaTunnel以其强大的数据集成能力&#xff0c;成为众多企业的首选。 但随着应用深入&#xff0c;企业面…