在Linux下使用wxWidgets进行跨平台GUI开发(二)

wxWidgets常见辅助类的应用示例

wxWidgets提供了一系列功能强大的辅助类(Helper Classes),涵盖了字符串处理、文件操作、XML解析、数据流、数据库和网络通信等功能,这些类为跨平台GUI开发提供了基础工具支持,帮助开发者完成各种任务。

wxWidgets库可用于创建控制台和图形界面(GUI)应用程序。本文将通过一些控制台应用程序的示例,阐述部分核心辅助类的使用方法。

Console示例

好,那现在让我们跟着ZetCode教程上的示例。第一个非常简单的控制台程序

一个非常简单的控制台程序:

cpp 复制代码
// console.cpp
#include <wx/wx.h> // 必须得加上这个头文件
#include <wx/string.h>

int main(int argc, char **argv)
{
    wxPuts(wxT("A wxWidgets console application"));
}

对应的CMakeLists.txt文件:

cmake 复制代码
cmake_minimum_required(VERSION 3.10)
project(console)

find_package(wxWidgets REQUIRED COMPONENTS core)
include(${wxWidgets_USE_FILE})

add_executable(${PROJECT_NAME} console.cpp)
target_link_libraries(${PROJECT_NAME} ${wxWidgets_LIBRARIES})
set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR})

然后因为现在是VS Code开发,所以需要改一个调试配置文件launch.json,找到

复制代码
"program": "${workspaceFolder}/hello",
更改为
"program": "${workspaceFolder}/console",
现在你应该能顺利构建编译运行,这将在控制台终端输出
A wxWidgets console application
好的,现在我们将console.cpp和CMakeLists.txt文件复制到Windows平台,是的,我们的目的是要跨平台的,现在我们来做这件事。
在Windows上找到一个工作空间(注意路径字符规范),还是创建test文件夹,把要复制的两个文件拷贝到里面。
进入cmd命令行,还是将构建文件放到build下。
cmake -B build

然后生成可执行文件大概会出错,需修改CMakeLists.txt文件(确保跨平台):

cmake 复制代码
cmake_minimum_required(VERSION 3.10)
project(console)

if(WIN32)
    find_package(wxWidgets 3.2.4 REQUIRED COMPONENTS core base adv html xml net aui stc xrc gl media qa richtext propgrid ribbon webview)
else()
    find_package(wxWidgets 3.2.4 REQUIRED COMPONENTS core base)
endif()

include(${wxWidgets_USE_FILE})
add_executable(${PROJECT_NAME} console.cpp)
target_link_libraries(${PROJECT_NAME} ${wxWidgets_LIBRARIES})

if(MSVC)
    target_include_directories(${PROJECT_NAME} PUBLIC "${wxWidgets_INCLUDE_DIRS}/msvc")
endif()

set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR})

现在可以构建并生成可执行文件了,在cmd中键入
cmake --build ./build

这会根据默认构建系统在build文件夹里生成程序。如果你安装了Visual Studio则默认使用msvc工具链,你将会在build下看到一个sln解决方案,你也可以打开解决方案在IDE下生成可执行程序。

wxString类示例

wxString是一个表示字符串的类。在下面的示例中,我们定义了三个wxString对象。我们通过加法运算将这些字符串组合成一个新的字符串。

字符串连接

cpp 复制代码
// addition.cpp
#include <wx/wx.h>
#include <wx/string.h>

int main(int argc, char **argv)
{
    wxString str1 = wxT("Linux");
    wxString str2 = wxT("Operating");
    wxString str3 = wxT("System");
    wxString str = str1 + wxT(" ") + str2 + wxT(" ") + str3;
    wxPuts(str);
}

输出:

复制代码
Linux Operating System

你可以练习使用CMake生成这个可执行程序,当然你可以在Linux终端使用

复制代码
g++ addition.cpp `wx-config --cxxflags --libs` -o addition

更简洁地生成可执行文件。

字符串格式化

cpp 复制代码
// formatted.cpp
#include <wx/wx.h>
#include <wx/string.h>

int main(int argc, char **argv)
{
    int flowers = 21;
    wxString str;
    str.Printf(wxT("There are %d red roses."), flowers);
    wxPuts(str);
}

输出:

复制代码
There are 21 red roses.

以下示例演示了如何检查一个字符串是否包含另一个字符串,为此我们使用了Contains方法。(注:根据编程语言或框架的不同,类似功能可能有不同命名,如includes()、find()、contains()等,但作用相同。)

字符串包含检查

cpp 复制代码
// contains.cpp
#include <wx/wx.h>
#include <wx/string.h>

int main(int argc, char **argv)
{
    wxString str = wxT("The history of my life");
    if (str.Contains(wxT("history"))) {
        wxPuts(wxT("Contains!"));
    }
    if (!str.Contains(wxT("plain"))) {
        wxPuts(wxT("Does not contain!"));
    }
}

输出:

复制代码
Contains!
Does not contain!

Len方法返回字符串中的字符数。(补充说明:对于多字节字符(如中文),不同语言处理方式可能不同,有些按字符数统计,有些按字节数统计)

字符串长度

cpp 复制代码
// length.cpp
#include <wx/wx.h>
#include <wx/string.h>

int main(int argc, char **argv)
{
    wxString str = wxT("The history of my life");
    wxPrintf(wxT("The string has %d characters\n"), str.Len());
}

输出:

复制代码
The string has 22 characters

大小写转换

cpp 复制代码
// cases.cpp
#include <wx/wx.h>
#include <wx/string.h>

int main(int argc, char **argv)
{
    wxString str = wxT("The history of my life");
    wxPuts(str.MakeLower());
    wxPuts(str.MakeUpper());
}

输出:

复制代码
the history of my life
THE HISTORY OF MY LIFE

实用工具函数

(编程概念说明:这类函数通常指不依赖对象状态、独立完成特定任务的辅助函数)

wxWidgets 提供了多个实用的工具函数,用于执行进程、获取用户主目录或获取操作系统名称。

在以下示例中,我们执行了 ls 命令(仅限 Unix 系统),为此我们使用了 wxShell 函数。

执行shell命令

cpp 复制代码
// shell.cpp
#include <wx/wx.h>
#include <wx/string.h>
#include <wx/utils.h>

int main(int argc, char **argv)
{
    wxShell(wxT("ls -l"));
}

这将输出当前路径下的文件统计信息。

接下来我们将获取用户主目录、操作系统名称、用户名、主机名以及内存空闲总量。

获取系统信息

cpp 复制代码
// system.cpp
#include <wx/wx.h>
#include <wx/string.h>
#include <wx/utils.h>

int main(int argc, char **argv)
{
    wxPuts(wxGetHomeDir());
    wxPuts(wxGetOsDescription());
    wxPuts(wxGetUserName());
    wxPuts(wxGetFullHostName());
    long mem = wxGetFreeMemory().ToLong();
    wxPrintf(wxT("Memory: %ld\n"), mem);
}

这将输出系统及用户等统计信息。

时间和日期处理

在wxWidgets中,我们提供了多个用于处理日期和时间的类。

该示例展示了以不同格式显示的当前日期或时间。

当前日期时间格式化

cpp 复制代码
// datetime.cpp
#include <wx/wx.h>
#include <wx/datetime.h>

int main(int argc, char **argv)
{
    wxDateTime now = wxDateTime::Now();
    wxString date1 = now.Format();
    wxString date2 = now.Format(wxT("%X"));
    wxString date3 = now.Format(wxT("%x"));
    wxPuts(date1);
    wxPuts(date2);
    wxPuts(date3);
}

输出示例:

复制代码
Wed Jun 11 16:18:09 2025
16:18:09
06/11/25

不同城市时间

cpp 复制代码
// datetime2.cpp
#include <wx/wx.h>
#include <wx/datetime.h>

int main(int argc, char **argv)
{
    wxDateTime now = wxDateTime::Now();
    wxPrintf(wxT(" Tokyo: %s\n"), now.Format(wxT("%a %T"), wxDateTime::GMT9).c_str());
    wxPrintf(wxT(" Moscow: %s\n"), now.Format(wxT("%a %T"), wxDateTime::MSD).c_str());
    wxPrintf(wxT("Budapest: %s\n"), now.Format(wxT("%a %T"), wxDateTime::CEST).c_str());
    wxPrintf(wxT(" London: %s\n"), now.Format(wxT("%a %T"), wxDateTime::WEST).c_str());
    wxPrintf(wxT("New York: %s\n"), now.Format(wxT("%a %T"), wxDateTime::EDT).c_str());
}

输出示例:

复制代码
 Tokyo: Wed 17:23:43
 Moscow: Wed 12:23:43
Budapest: Wed 10:23:43
 London: Wed 09:23:43
New York: Wed 04:23:43

日期跨度

以下示例展示了如何向日期/时间添加日期跨度。我们将当前时间增加一个月。

cpp 复制代码
// datespan.cpp
#include <wx/wx.h>
#include <wx/datetime.h>

int main(int argc, char **argv)
{
    wxDateTime now = wxDateTime::Now();
    wxString date1 = now.Format(wxT("%B %d %Y"));
    wxPuts(date1);
    wxDateSpan span(0, 1);
    wxDateTime then = now.Add(span);
    wxString date2 = then.Format(wxT("%B %d %Y"));
    wxPuts(date2);
}

输出示例:

复制代码
June 11 2025
July 11 2025

文件操作

wxWidgets 提供了多个类来简化文件操作。这是对文件的底层访问,与流式操作不同。

在以下示例中,我们使用 wxFile 类创建新文件并写入数据,同时会检测文件是否已打开。需注意:创建文件时会自动保持打开状态。

创建和写入文件

cpp 复制代码
// createfile.cpp
#include <wx/wx.h>
#include <wx/file.h>

int main(int argc, char **argv)
{
    wxString str = wxT("You make me want to be a better man.\n");
    wxFile file;
    file.Create(wxT("quote"), true);
    if (file.IsOpened())
        wxPuts(wxT("the file is opened"));
    file.Write(str);
    file.Close();
    if (!file.IsOpened())
        wxPuts(wxT("the file is not opened"));
}

终端交互示例:

复制代码
$ ls quote
ls: quote: No such file or directory
$ ./createfile
the file is opened
the file is not opened
$ cat quote
You make me want to be a better man.

wxTextFile 是一个简易的文本文件操作类,支持以行为单位处理文本文件。相比 wxFile 类,使用这个类会更加便捷。

在接下来的示例中,我们将输出文件的行数、首行和末行内容,最终读取并显示文件的全部内容。

文本文件操作

cpp 复制代码
// readfile.cpp
#include <wx/wx.h>
#include <wx/textfile.h>

int main(int argc, char **argv)
{
    wxTextFile file(wxT("test.c"));
    file.Open();
    wxPrintf(wxT("Number of lines: %d\n"), file.GetLineCount());
    wxPrintf(wxT("First line: %s\n"), file.GetFirstLine().c_str());
    wxPrintf(wxT("Last line: %s\n"), file.GetLastLine().c_str());
    wxPuts(wxT("----------------------------------------"));
    wxString s;
    for ( s = file.GetFirstLine(); !file.Eof();
        s = file.GetNextLine() )
    {
        wxPuts(s);
    }
    file.Close();
}

test.c内容:

复制代码
#include <glib.h>
#include <glib/gstdio.h>

int main() {
    g_mkdir("/home/vronskij/test", S_IRWXU);
}

输出:

复制代码
Number of lines: 8
First line: #include <glib.h>
Last line: }
----------------------------------------
#include <glib.h>
#include <glib/gstdio.h>

int main() {
    g_mkdir("/home/vronskij/test", S_IRWXU);
}

目录枚举

在以下示例中,我们将打印当前工作目录下的所有文件和目录。

cpp 复制代码
// dir.cpp
#include <wx/wx.h>
#include <wx/dir.h>
#include <wx/filefn.h>

int main(int argc, char **argv)
{
    wxDir dir(wxGetCwd());
    wxString file;
    bool cont = dir.GetFirst(&file, wxEmptyString, wxDIR_FILES | wxDIR_DIRS);
    while (cont) {
        wxPuts(file);
        cont = dir.GetNext(&file);
    }
}

输出示例:

复制代码
dir
dir.cpp
temp
console
basic.cpp
basic
quote
createfile
console.cpp
basic.cpp~
test.c
console.cpp~
......

辅助类的应用示例暂且介绍到这里了,后续进行正式的wxWidgets开发说明。

相关推荐
南岩亦凛汀5 天前
在Linux下使用wxWidgets进行跨平台GUI开发
c++·跨平台·gui·开源框架·工程实战教程
sg_knight8 天前
Flutter嵌入式开发实战 ——从树莓派到智能家居控制面板,打造工业级交互终端
android·前端·flutter·ios·智能家居·跨平台
胡斌附体10 天前
uniapp中view标签使用范围
uni-app·跨平台·标签·view·范围
sg_knight17 天前
Flutter Web 3.0革命:用WebGPU实现浏览器端实时光追渲染,性能提升300%
前端·flutter·跨平台·web
十五年专注C++开发17 天前
CMake指令:set()
开发语言·c++·跨平台·编译工具·cmake·自动化编译工具
sg_knight19 天前
Flutter跨平台通信实战|3步打通Android原生能力,实现底层API调用!
android·前端·javascript·flutter·跨平台·web·双向通信
伊织code20 天前
macOS 安装 PostgreSQL
数据库·macos·postgresql·gui·安装·客户端·psql
机器视觉知识推荐、就业指导1 个月前
Qt/C++面试【速通笔记五】—子线程与GUI线程安全交互
c++·qt·面试·gui·子线程
钟剑锋-JeffChong1 个月前
Qt快速上手:QSettings高效配置读写实战指南
跨平台·qt5·配置管理·qsettings