当前位置: 首页 > news >正文

Python GUI应用程序开发之wxPython使用详解


概要

wxPython是一个强大的跨平台GUI工具包,它使用Python编程语言开发,提供了丰富的控件功能。如果你是一名Python开发者,而且希望创建一个功能齐全的桌面应用程序,那么wxPython是一个值得考虑的选择。


什么是wxPython

wxPython是wxWidgets C++库的Python绑定版本,它支持各种操作系统,包括Windows、Linux和macOS。wxPython提供了各种标准控件,如按钮、文本框、下拉列表、菜单、对话框等,以及许多高级控件,如网格、树形结构、列表框等,使开发者可以创建复杂的GUI应用程序。

安装

安装wxPython非常简单。只需在终端或命令提示符中键入以下命令:

pip install wxPython

然后就可以开始使用wxPython来创建GUI应用程序了。

创建一个GUI应用程序

让我们来看一个简单的wxPython示例程序。下面的程序创建一个简单的窗口,其中包含一个按钮。当用户单击按钮时,程序将显示一个对话框。

import wxclass MyFrame(wx.Frame):def __init__(self, parent, title):wx.Frame.__init__(self, parent, title=title, size=(300, 200))self.panel = wx.Panel(self)self.button = wx.Button(self.panel, label="Click Me")self.Bind(wx.EVT_BUTTON, self.on_button_click, self.button)self.Show(True)def on_button_click(self, event):wx.MessageBox('Hello wxPython', 'Message', wx.OK | wx.ICON_INFORMATION)app = wx.App(False)
frame = MyFrame(None, 'Hello wxPython')
app.MainLoop()

在这个例子中,先定义了一个名为MyFrame的类,该类继承自wx.Frame类,并重写了它的构造函数。在构造函数中,我们创建了一个名为panel的wx.Panel对象,该对象是一个容器,用于包含其他控件。我们还创建了一个名为button的wx.Button对象,并将其添加到panel中。最后,使用Bind()方法将wx.EVT_BUTTON事件与on_button_click()方法关联起来。
on_button_click()方法是一个事件处理程序,它在用户单击按钮时被调用。在这个方法中,使用wx.MessageBox()方法创建了一个简单的消息框。
最后,创建一个wx.App对象,并将它的参数设置为False,这表示我们不希望wxPython创建一个控制台窗口。然后创建一个MyFrame对象,并将其显示出来。

控件

wxPython支持各种控件,包括文本框、按钮、下拉列表、菜单、对话框等。下面是一些常用的wxPython控件:

wx.TextCtrl

wx.TextCtrl控件用于显示和编辑文本。它可以用于单行文本框或多行文本框。

import wxclass MyFrame(wx.Frame):def __init__(self, parent, title):wx.Frame.__init__(self, parent, title=title, size=(300, 200))self.panel = wx.Panel(self)self.textctrl = wx.TextCtrl(self.panel, style=wx.TE_MULTILINE)app = wx.App(False)
frame = MyFrame(None, 'TextCtrl Example')
frame.Show(True)
app.MainLoop()

在这个例子中,我们创建了一个名为textctrl的wx.TextCtrl对象,并将其添加到panel中。还使用style参数指定了wx.TE_MULTILINE样式,这表示这个文本框是一个多行文本框。

wx.Button

wx.Button控件用于创建按钮。

import wxclass MyFrame(wx.Frame):def __init__(self, parent, title):wx.Frame.__init__(self, parent, title=title, size=(300, 200))self.panel = wx.Panel(self)self.button = wx.Button(self.panel, label="Click Me")app = wx.App(False)
frame = MyFrame(None, 'Button Example')
frame.Show(True)
app.MainLoop()

在这个例子中,我们创建了一个名为button的wx.Button对象,并将其添加到panel中。

wx.StaticText

wx.StaticText控件用于显示静态文本。

import wxclass MyFrame(wx.Frame):def __init__(self, parent, title):wx.Frame.__init__(self, parent, title=title, size=(300, 200))self.panel = wx.Panel(self)self.statictext = wx.StaticText(self.panel, label="Hello World")app = wx.App(False)
frame = MyFrame(None, 'StaticText Example')
frame.Show(True)
app.MainLoop()

在这个例子中,我们创建了一个名为statictext的wx.StaticText对象,并将其添加到panel中。

布局管理器

wxPython支持多种布局管理器,包括BoxSizer、GridSizer、FlexGridSizer、GridBagSizer等。布局管理器用于控制控件的位置和大小。

BoxSizer

BoxSizer布局管理器用于在水平或垂直方向上排列控件。下面是一个使用BoxSizer布局管理器的例子:

import wxclass MyFrame(wx.Frame):def __init__(self, parent, title):super(MyFrame, self).__init__(parent, title=title, size=(300, 200))self.InitUI()def InitUI(self):panel = wx.Panel(self)vbox = wx.BoxSizer(wx.VERTICAL)hbox1 = wx.BoxSizer(wx.HORIZONTAL)st = wx.StaticText(panel, label='This is a static text')hbox1.Add(st, proportion=1)vbox.Add(hbox1, flag=wx.EXPAND|wx.LEFT|wx.RIGHT|wx.TOP, border=10)hbox2 = wx.BoxSizer(wx.HORIZONTAL)btn1 = wx.Button(panel, label='Quit')btn2 = wx.Button(panel, label='Open')hbox2.Add(btn1, proportion=0)hbox2.Add(btn2, proportion=0, flag=wx.LEFT|wx.BOTTOM, border=5)vbox.Add(hbox2, flag=wx.ALIGN_RIGHT|wx.RIGHT, border=10)panel.SetSizer(vbox)self.Centre()self.Show(True)app = wx.App(False)
frame = MyFrame(None, 'BoxSizer Example')
app.MainLoop()

在这个例子中,创建了一个wx.Frame对象,并为它设置了标题和大小。我们还创建了一个wx.Panel对象,并将其添加到框架中。使用wx.BoxSizer(wx.VERTICAL)创建了一个垂直方向的BoxSizer对象,并将其设置为panel的sizer。
创建两个wx.BoxSizer(wx.HORIZONTAL)对象,一个用于放置静态文本控件,一个用于放置两个按钮控件。使用wx.StaticText创建了一个静态文本控件,并将其添加到第一个水平方向的BoxSizer对象中。使用wx.Button创建了两个按钮控件,并将它们添加到第二个水平方向的BoxSizer对象中。

GridSizer

GridSizer布局管理器用于创建网格布局。下面是一个使用GridSizer布局管理器的例子:

import wxclass MyFrame(wx.Frame):def __init__(self, parent, title):wx.Frame.__init__(self, parent, title=title, size=(300, 200))self.panel = wx.Panel(self)grid = wx.GridSizer(2, 2, 10, 10)self.statictext1 = wx.StaticText(self.panel, label="Name:")self.statictext2 = wx.StaticText(self.panel, label="Age:")self.textctrl1 = wx.TextCtrl(self.panel)self.textctrl2 = wx.TextCtrl(self.panel)grid.Add(self.statictext1, 0, wx.ALIGN_RIGHT)grid.Add(self.textctrl1, 0, wx.EXPAND)grid.Add(self.statictext2, 0, wx.ALIGN_RIGHT)grid.Add(self.textctrl2, 0, wx.EXPAND)self.panel.SetSizer(grid)app = wx.App(False)
frame = MyFrame(None, 'GridSizer Example')
frame.Show(True)
app.MainLoop()

在这个例子中,我们创建了一个名为grid的wx.GridSizer对象,并将其添加到panel中。该网格布局由两行两列组成,每个单元格之间的间距为10像素。

FlexGridSizer

FlexGridSizer布局管理器用于创建灵活的网格布局。它允许某些行和/或列具有不同的大小和/或比例。下面是一个使用FlexGridSizer布局管理器的例子:

import wxclass MyFrame(wx.Frame):def __init__(self, parent, title):wx.Frame.__init__(self, parent, title=title, size=(300, 200))self.panel = wx.Panel(self)flexgrid = wx.FlexGridSizer(2, 2, 10, 10)self.statictext1 = wx.StaticText(self.panel, label="Name:")self.statictext2 = wx.StaticText(self.panel, label="Age:")self.textctrl1 = wx.TextCtrl(self.panel)self.textctrl2 = wx.TextCtrl(self.panel)flexgrid.Add(self.statictext1, 0, wx.ALIGN_RIGHT)flexgrid.Add(self.textctrl1, 0, wx.EXPAND)flexgrid.Add(self.statictext2, 1, wx.ALIGN_RIGHT)flexgrid.Add(self.textctrl2, 1, wx.EXPAND)flexgrid.AddGrowableCol(1)self.panel.SetSizer(flexgrid)app = wx.App(False)
frame = MyFrame(None, 'FlexGridSizer Example')
frame.Show(True)
app.MainLoop()

在这个例子中,我们创建了一个名为flexgrid的wx.FlexGridSizer对象,并将其添加到panel中。该网格布局由两行两列组成,每个单元格之间的间距为10像素。第一行和第二行的第二列具有相同的大小和比例,因为它们都使用了默认值。但是,我们使用了AddGrowableCol(1)方法,使第二列变得可扩展,这意味着当窗口调整大小时,第二列将增长并填充任何可用空间。

WrapSizer

WrapSizer布局管理器用于创建自动换行的布局。它允许您添加任意数量的控件,并自动将它们排列成多行。下面是一个使用WrapSizer布局管理器的例子:

import wxclass MyFrame(wx.Frame):def __init__(self, parent, title):wx.Frame.__init__(self, parent, title=title, size=(300, 200))self.panel = wx.Panel(self)wrapsizer = wx.WrapSizer(wx.HORIZONTAL)self.button1 = wx.Button(self.panel, label="Button 1")self.button2 = wx.Button(self.panel, label="Button 2")self.button3 = wx.Button(self.panel, label="Button 3")self.button4 = wx.Button(self.panel, label="Button 4")self.button5 = wx.Button(self.panel, label="Button 5")wrapsizer.Add(self.button1, 0, wx.EXPAND|wx.ALL, 5)wrapsizer.Add(self.button2, 0, wx.EXPAND|wx.ALL, 5)wrapsizer.Add(self.button3, 0, wx.EXPAND|wx.ALL, 5)wrapsizer.Add(self.button4, 0, wx.EXPAND|wx.ALL, 5)wrapsizer.Add(self.button5, 0, wx.EXPAND|wx.ALL, 5)self.panel.SetSizer(wrapsizer)app = wx.App(False)
frame = MyFrame(None, 'WrapSizer Example')
frame.Show(True)
app.MainLoop()

在这个例子中,我们创建了一个名为wrapsizer的wx.WrapSizer对象,并将其添加到panel中。该布局管理器使用水平方向,因此当添加的控件超过可用空间时,它们将自动换行到下一行。

ScrolledWindow

ScrolledWindow控件允许您在包含大量内容的窗口中滚动内容。下面是一个使用ScrolledWindow控件的例子:

import wxclass MyFrame(wx.Frame):def __init__(self, parent, title):wx.Frame.__init__(self, parent, title=title, size=(300, 200))self.panel = wx.Panel(self)scrolled = wx.ScrolledWindow(self.panel, -1)vbox = wx.BoxSizer(wx.VERTICAL)for i in range(30):label = "Line {}".format(i+1)statictext = wx.StaticText(scrolled, label=label)vbox.Add(statictext, 0, wx.EXPAND|wx.ALL, 5)scrolled.SetSizer(vbox)scrolled.SetScrollRate(0, 10)app = wx.App(False)
frame = MyFrame(None, 'ScrolledWindow Example')
frame.Show(True)
app.MainLoop()

在这个例子中,我们创建了一个名为scrolled的wx.ScrolledWindow对象,并将其添加到panel中。使用wx.BoxSizer创建了一个垂直布局,其中包含30个静态文本标签。将vbox布局添加到scrolled窗口中,并使用SetSizer方法将布局应用于窗口。
为了启用滚动,我们使用SetScrollRate方法设置垂直滚动条的滚动速度为10个像素。

GridBagSizer

GridBagSizer布局管理器允许您以网格的形式布置控件,并允许您自由控制每个单元格中控件的大小和位置。下面是一个使用GridBagSizer布局管理器的例子:

import wxclass MyFrame(wx.Frame):def __init__(self, parent, title):wx.Frame.__init__(self, parent, title=title, size=(300, 200))self.panel = wx.Panel(self)gridbag = wx.GridBagSizer(5, 5)self.button1 = wx.Button(self.panel, label="Button 1")self.button2 = wx.Button(self.panel, label="Button 2")self.button3 = wx.Button(self.panel, label="Button 3")self.button4 = wx.Button(self.panel, label="Button 4")self.button5 = wx.Button(self.panel, label="Button 5")gridbag.Add(self.button1, pos=(0, 0), span=(1, 1), flag=wx.EXPAND|wx.ALL, border=5)gridbag.Add(self.button2, pos=(0, 1), span=(1, 1), flag=wx.EXPAND|wx.ALL, border=5)gridbag.Add(self.button3, pos=(1, 0), span=(1, 2), flag=wx.EXPAND|wx.ALL, border=5)gridbag.Add(self.button4, pos=(2, 0), span=(1, 1), flag=wx.EXPAND|wx.ALL, border=5)gridbag.Add(self.button5, pos=(2, 1), span=(1, 1), flag=wx.EXPAND|wx.ALL, border=5)self.panel.SetSizer(gridbag)app = wx.App(False)
frame = MyFrame(None, 'GridBagSizer Example')
frame.Show(True)
app.MainLoop()

在这个例子中,我们创建了一个名为gridbag的wx.GridBagSizer对象,并将其添加到panel中。使用Add方法将5个按钮添加到网格中,并使用pos参数指定按钮在网格中的位置,使用span参数指定按钮跨越的行数和列数。
我们还可以使用flag参数来指定控件在单元格中的对齐方式和填充方式,以及使用border参数来指定控件周围的边框宽度。

颜色选择器和文件对话框

除了各种布局管理器和控件之外,wxPython还提供了一些方便的对话框和工具类,用于处理常见的任务,例如选择颜色或文件。下面是两个示例:

import wxclass MyFrame(wx.Frame):def __init__(self, parent, title):wx.Frame.__init__(self, parent, title=title, size=(300, 200))self.panel = wx.Panel(self)self.colorbutton = wx.Button(self.panel, label="Choose Color", pos=(50, 50))self.filebutton = wx.Button(self.panel,label="Choose File", pos=(150, 50))self.colorbutton.Bind(wx.EVT_BUTTON, self.OnColor)self.filebutton.Bind(wx.EVT_BUTTON, self.OnFile)def OnColor(self, event):dlg = wx.ColourDialog(self.panel)if dlg.ShowModal() == wx.ID_OK:color = dlg.GetColourData().GetColour().Get()print("You selected color:", color)dlg.Destroy()def OnFile(self, event):dlg = wx.FileDialog(self.panel, "Choose a file", wildcard="*.txt")if dlg.ShowModal() == wx.ID_OK:path = dlg.GetPath()print("You selected file:", path)dlg.Destroy()app = wx.App(False)
frame = MyFrame(None, 'Dialogs and Tools Example')
frame.Show(True)
app.MainLoop()

在这个例子中,我们创建了两个wx.Button对象,一个用于选择颜色,一个用于选择文件。我们将它们添加到panel中,并为它们绑定了OnColor和OnFile方法,用于处理单击事件。

当用户单击颜色选择按钮时,我们创建了一个wx.ColourDialog对象,并使用GetColourData方法获取用户选择的颜色。当用户单击文件选择按钮时,我们创建了一个wx.FileDialog对象,并使用GetPath方法获取用户选择的文件路径。

最后,本文介绍了wxPython中的一些常见布局管理器和控件,以及如何使用对话框和工具类。希望这篇文章对您学习和使用wxPython有所帮助。

相关文章:

Python GUI应用程序开发之wxPython使用详解

概要 wxPython是一个强大的跨平台GUI工具包,它使用Python编程语言开发,提供了丰富的控件功能。如果你是一名Python开发者,而且希望创建一个功能齐全的桌面应用程序,那么wxPython是一个值得考虑的选择。 什么是wxPython wxPython…...

【电子学会真题】青少年软件编程(C语言)等级考试试卷(一级) 2021年9月

试卷下载 pdf 格式下载:https://download.csdn.net/download/SHUTIAN2010/88255543 word 格式下载:https://download.csdn.net/download/SHUTIAN2010/88255558 1.计算乘积 一行两个整数a、b,以空格分隔。(0&#xff1…...

学习完毕JavaSE的感想

今天,把Java复习完毕了,之前学习的时候,学校里学的总是有限的 ,自己上手操作之后才发觉差的很多,部署服务器发现要学操作系统,学完了web基础 ,又发现还得学前后端分离vue react这些,…...

FastJson的学习

fastjson是阿里巴巴的开源JSON解析库&#xff0c;它可以解析JSON格式的字符串&#xff0c;支持将Java Bean序列化为JSON字符串&#xff0c;也可以从JSON字符串反序列化到JavaBean。 fastjson是json的序列化和反序列化 一、添加依赖 <dependency><groupId>com.ali…...

python scrapy框架

scrapy概述 Scrapy&#xff0c;Python开发的一个快速、高层次的屏幕抓取和web抓取框架&#xff0c;用于抓取web站点并从页面中提取结构化的数据。Scrapy用途广泛&#xff0c;可以用于数据挖掘、监测和自动化测试 scrapy安装 pip install scrapy -i https://pypi.tuna.tsinghua…...

滑动窗口系列3-Leetcode134题加油站

在一条环路上有 n 个加油站&#xff0c;其中第 i 个加油站有汽油 gas[i] 升。 你有一辆油箱容量无限的的汽车&#xff0c;从第 i 个加油站开往第 i1 个加油站需要消耗汽油 cost[i] 升。你从其中的一个加油站出发&#xff0c;开始时油箱为空。 给定两个整数数组 gas 和 cost &…...

LOIC(low orbit ion cannon)

前言 重要的话说三遍&#xff1a; 该程序仅用于学习用途&#xff0c;请勿用于非法行为上&#xff01;&#xff01;&#xff01; 该程序仅用于学习用途&#xff0c;请勿用于非法行为上&#xff01;&#xff01;&#xff01; 该程序仅用于学习用途&#xff0c;请勿用于非法行为上…...

从格灵深瞳中报稳定盈利,看AI公司的核心竞争力

2023年过半&#xff0c;人工智能产业话题不断。大模型和AIGC掀起热潮&#xff0c;让众多AI公司开始进入新一轮竞赛。但与此同时&#xff0c;不少AI公司依然处于亏损中&#xff0c;研发投入和商业产出难以实现正循环。如何形成健康的商业模式&#xff0c;仍是一大挑战。 AI公司…...

理解 Databend Cluster key 原理及使用

Databend Cluster Key 是指 Databend 可以按声明的 key 排序存储&#xff0c;主要用于用户对时间响应比较高&#xff0c;同时愿意为这个 cluster key 进行额排序操作的用户。 Databend 只支持一个 Cluster key&#xff0c;Cluster key中可以包含多列及表达式。 基本语法 -- 语…...

C++day3(类、this指针、类中的特殊成员函数)

一、Xmind整理&#xff1a; 二、上课笔记整理&#xff1a; 1.类的应用实例 #include <iostream> using namespace std;class Person { private:string name; public:int age;int high;void set_name(string n); //在类内声明函数void show(){cout << "na…...

Qt中的配置文件:实现个性化应用程序配置与保存加载

一、前言 在现代软件开发中,用户对于应用程序的个性化配置和设置变得越来越重要。为了满足用户需求并提供更好的用户体验,开发人员常常需要实现一种机制,以便在每次启动应用程序时能够记住用户上次的配置。这样用户就可以方便地恢复到他们熟悉的环境,无需重新进行所有设置…...

Navicat激活时出现rsa public key not find错误

Navicat激活时出现rsa public key not find错误 在激活时&#xff0c;先不打开应用&#xff0c;先用管理员身份打开注册机Navicat_Keygen_Patch_v5.6_By_DFoX.exe&#xff0c;Navicat v15——>MySql——>Simplified Chinese——>Patch&#xff0c;执行完这些步骤之后…...

FFmpeg5.0源码阅读——URLContext和URLProtocol

摘要&#xff1a;本文描述FFmpeg中URLContext和URLProtocal的实现。   关键字&#xff1a;URLContext、URLProtocal FFmpeg中URLProtocol是具体的协议的抽象&#xff0c;其中定义了对应协议的抽象&#xff0c;其中包含了具体协议的操作函数指针。而URLContext是对协议操作的抽…...

Qt的输出

目录 基本分类 C风格输出 C风格 可以抑制输出 方法一 方法二 在Qt中进行log输出, 一般不使用c中的printf, 也不是使用C中的cout, Qt框架提供了专门用于日志输出的类, 头文件名为 QDebug。 基本分类 qDebug&#xff1a;调试信息提示 qInfo &#xff1a;输出信息 qWarnin…...

长胜证券:久违普涨再现 大盘回升有望加速

获得利好支撑后&#xff0c;大盘开始继续反弹。 沪指周二一路震动反弹&#xff0c;站上3100点整数关口后继续上攻并打破10日均线限制。深成指同样低开高走&#xff0c;全日体现明显强于沪指。 到收盘&#xff0c;沪指报收3135.89点&#xff0c;上涨1.2%&#xff1b;深成指报收…...

WPF .NET 7.0学习整理(一)

参照文档进行不系统的整理&#xff0c;看到那写到那O.o 依赖属性 DependencyProperty&#xff1a;使用专有字段支持属性的标准模式的替代方法。 DependencyObject&#xff1a;定义了可以注册和拥有依赖属性的基类。 public static readonly DependencyProperty IsSpinningPr…...

数据分析简介

判断采集数据的有效性和进行数据校准是数据处理中重要的步骤。以下是一些常见的方法和步骤可以帮助你进行数据有效性的判断和数据校准&#xff1a; 数据有效性判断: 数据范围&#xff1a;检查数据是否落在合理的范围内。根据具体情况&#xff0c;确定真实数据的上下限&#xff…...

解读未知:文本识别算法的突破与实际应用

解读未知&#xff1a;文本识别算法的突破与实际应用 1.文本识别算法理论 背景介绍 文本识别是OCR&#xff08;Optical Character Recognition&#xff09;的一个子任务&#xff0c;其任务为识别一个固定区域的的文本内容。在OCR的两阶段方法里&#xff0c;它接在文本检测后面…...

[第七届蓝帽杯全国大学生网络安全技能大赛 蓝帽杯 2023]——Web方向部分题 详细Writeup

Web LovePHP 你真的熟悉PHP吗&#xff1f; 源码如下 <?php class Saferman{public $check True;public function __destruct(){if($this->check True){file($_GET[secret]);}}public function __wakeup(){$this->checkFalse;} } if(isset($_GET[my_secret.flag]…...

el-backtop返回顶部的使用

2023.8.26今天我学习了如何使用el-backtop组件进行返回页面顶部的效果&#xff0c;效果如&#xff1a; <el-backtop class"el-backtop"style"right: 20px; bottom: 150px;"><i class"el-icon-caret-top"></i></el-backtop&…...

三维GIS开发cesium智慧地铁教程(5)Cesium相机控制

一、环境搭建 <script src"../cesium1.99/Build/Cesium/Cesium.js"></script> <link rel"stylesheet" href"../cesium1.99/Build/Cesium/Widgets/widgets.css"> 关键配置点&#xff1a; 路径验证&#xff1a;确保相对路径.…...

遍历 Map 类型集合的方法汇总

1 方法一 先用方法 keySet() 获取集合中的所有键。再通过 gey(key) 方法用对应键获取值 import java.util.HashMap; import java.util.Set;public class Test {public static void main(String[] args) {HashMap hashMap new HashMap();hashMap.put("语文",99);has…...

QMC5883L的驱动

简介 本篇文章的代码已经上传到了github上面&#xff0c;开源代码 作为一个电子罗盘模块&#xff0c;我们可以通过I2C从中获取偏航角yaw&#xff0c;相对于六轴陀螺仪的yaw&#xff0c;qmc5883l几乎不会零飘并且成本较低。 参考资料 QMC5883L磁场传感器驱动 QMC5883L磁力计…...

【机器视觉】单目测距——运动结构恢复

ps&#xff1a;图是随便找的&#xff0c;为了凑个封面 前言 在前面对光流法进行进一步改进&#xff0c;希望将2D光流推广至3D场景流时&#xff0c;发现2D转3D过程中存在尺度歧义问题&#xff0c;需要补全摄像头拍摄图像中缺失的深度信息&#xff0c;否则解空间不收敛&#xf…...

全面解析各类VPN技术:GRE、IPsec、L2TP、SSL与MPLS VPN对比

目录 引言 VPN技术概述 GRE VPN 3.1 GRE封装结构 3.2 GRE的应用场景 GRE over IPsec 4.1 GRE over IPsec封装结构 4.2 为什么使用GRE over IPsec&#xff1f; IPsec VPN 5.1 IPsec传输模式&#xff08;Transport Mode&#xff09; 5.2 IPsec隧道模式&#xff08;Tunne…...

HarmonyOS运动开发:如何用mpchart绘制运动配速图表

##鸿蒙核心技术##运动开发##Sensor Service Kit&#xff08;传感器服务&#xff09;# 前言 在运动类应用中&#xff0c;运动数据的可视化是提升用户体验的重要环节。通过直观的图表展示运动过程中的关键数据&#xff0c;如配速、距离、卡路里消耗等&#xff0c;用户可以更清晰…...

IP如何挑?2025年海外专线IP如何购买?

你花了时间和预算买了IP&#xff0c;结果IP质量不佳&#xff0c;项目效率低下不说&#xff0c;还可能带来莫名的网络问题&#xff0c;是不是太闹心了&#xff1f;尤其是在面对海外专线IP时&#xff0c;到底怎么才能买到适合自己的呢&#xff1f;所以&#xff0c;挑IP绝对是个技…...

莫兰迪高级灰总结计划简约商务通用PPT模版

莫兰迪高级灰总结计划简约商务通用PPT模版&#xff0c;莫兰迪调色板清新简约工作汇报PPT模版&#xff0c;莫兰迪时尚风极简设计PPT模版&#xff0c;大学生毕业论文答辩PPT模版&#xff0c;莫兰迪配色总结计划简约商务通用PPT模版&#xff0c;莫兰迪商务汇报PPT模版&#xff0c;…...

Windows安装Miniconda

一、下载 https://www.anaconda.com/download/success 二、安装 三、配置镜像源 Anaconda/Miniconda pip 配置清华镜像源_anaconda配置清华源-CSDN博客 四、常用操作命令 Anaconda/Miniconda 基本操作命令_miniconda创建环境命令-CSDN博客...

MacOS下Homebrew国内镜像加速指南(2025最新国内镜像加速)

macos brew国内镜像加速方法 brew install 加速formula.jws.json下载慢加速 &#x1f37a; 最新版brew安装慢到怀疑人生&#xff1f;别怕&#xff0c;教你轻松起飞&#xff01; 最近Homebrew更新至最新版&#xff0c;每次执行 brew 命令时都会自动从官方地址 https://formulae.…...