创建wxWidgets应用程序

在本文中,我们将了解创建wxWidgets应用程序所需的基础知识。首先创建一个简单的示例程序,展示如何显示图标;接着通过另一个示例演示事件的使用方法;最后探讨wxWidgets应用程序中控件之间的通信机制。

一个简单的应用程序

首先我们创建一个非常基础的wxWidgets程序。

// simple.h
#include <wx/wx.h> class Simple : public wxFrame
{
public:
Simple(const wxString& title); }; // simple.cpp
#include "simple.h" Simple::Simple(const wxString& title)
: wxFrame(NULL, wxID_ANY, title, wxDefaultPosition, wxSize(250, 150))
{
Centre();
} // main.h
#include <wx/wx.h> class MyApp : public wxApp
{
public:
virtual bool OnInit();
}; // main.cpp
#include "main.h"
#include "simple.h" IMPLEMENT_APP(MyApp) bool MyApp::OnInit()
{
Simple *simple = new Simple(wxT("Simple"));
simple->Show(true); return true;
}

用CMake构建工具,须编写CMakeLists.txt

cmake_minimum_required(VERSION 3.10)
project(simple) if(WIN32)
find_package(wxWidgets 3.2 REQUIRED COMPONENTS core base CONFIG)
else()
find_package(wxWidgets 3.2 REQUIRED COMPONENTS core base)
endif() if(wxWidgets_USE_FILE) # not defined in CONFIG mode
include(${wxWidgets_USE_FILE})
endif() set(SRC_FILES
main.cpp
simple.cpp
) # Define the build target for the executable, e.g. windows application.
add_executable(${PROJECT_NAME} WIN32 MACOSX_BUNDLE ${SRC_FILES})
target_link_libraries(${PROJECT_NAME} ${wxWidgets_LIBRARIES}) if(MSVC)
target_include_directories(${PROJECT_NAME} PUBLIC "${wxWidgets_INCLUDE_DIRS}/msvc")
endif() if(CMAKE_SIZEOF_VOID_P EQUAL 8)
message(STATUS "Configuring for 64-bit build.")
set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/out)
if(NOT MSVC)
set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/out/${CMAKE_BUILD_TYPE})
endif() else()
message(STATUS "Configuring for 32-bit build.")
set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/out/b32)
if(NOT MSVC)
set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/out/b32/${CMAKE_BUILD_TYPE})
endif()
endif()

现在,生成的可执行程序将会放在out文件夹内部。值得一提的是CMake采用Config模式在Windows下构建wxWidgets应用程序更好用,而在Linux下这个模式反而更麻烦了。

这个非常基础的示例在屏幕上显示了一个小窗口。该窗口位于屏幕中央。

Centre(); //这个方法将窗口在屏幕上水平和垂直居中。

IMPLEMENT_APP(MyApp) //实现应用程序的代码被隐藏在这个宏后面。

这段代码通常是复制粘贴复用的,我们一般不需要关心它。

运行效果例如在Linux下将显示

应用程序图标

在本示例中,我们为应用程序提供了一个图标。在窗口左上角显示小图标已成为标准做法,该图标是程序的图形标识。

// icon.h
#include <wx/wx.h> class Icon : public wxFrame
{
public:
Icon(const wxString& title); }; // icon.cpp
#include "icon.h" Icon::Icon(const wxString& title)
: wxFrame(NULL, wxID_ANY, title, wxDefaultPosition, wxSize(250, 150))
{
SetIcon(wxIcon(wxT("web.xpm")));
Centre();
} // main.h
#include <wx/wx.h> class MyApp : public wxApp
{
public:
virtual bool OnInit();
}; // main.cpp
#include "main.h"
#include "icon.h" IMPLEMENT_APP(MyApp) bool MyApp::OnInit()
{
Icon *icon = new Icon(wxT("Icon"));
icon->Show(true); return true;
}

在我们的示例中,我们展示了一个小小的网页图标。

SetIcon(wxIcon(wxT("web.xpm")));

只需一行代码即可显示应用程序图标。XPM(X PixMap)是一种ASCII图像格式。

一个简单的按钮

在以下示例中,我们将在框架部件上创建一个按钮。我们将展示如何创建一个简单的事件处理器。

// button.h
#include <wx/wx.h> class Button : public wxFrame
{
public:
Button(const wxString& title); void OnQuit(wxCommandEvent & event);
}; // button.cpp
#include "button.h" Button::Button(const wxString& title)
: wxFrame(NULL, wxID_ANY, title, wxDefaultPosition, wxSize(270, 150))
{
wxPanel *panel = new wxPanel(this, wxID_ANY); wxButton *button = new wxButton(panel, wxID_EXIT, wxT("Quit"),
wxPoint(20, 20));
Connect(wxID_EXIT, wxEVT_COMMAND_BUTTON_CLICKED,
wxCommandEventHandler(Button::OnQuit));
button->SetFocus();
Centre();
} void Button::OnQuit(wxCommandEvent & WXUNUSED(event))
{
Close(true);
} // main.h
#include <wx/wx.h> class MyApp : public wxApp
{
public:
virtual bool OnInit();
}; // main.cpp
#include "main.h"
#include "button.h" IMPLEMENT_APP(MyApp) bool MyApp::OnInit()
{ Button *btnapp = new Button(wxT("Button"));
btnapp->Show(true); return true;
}

首先我们创建一个 wxPanel 部件,它将被放置在 wxFrame 部件内部。

我们创建一个 wxButton 部件,将其放置在面板上。我们为按钮使用了预定义的 wxID_EXIT ID,这会使按钮上显示一个小的退出图标。按钮的标签是"退出"(Quit)。按钮被手动定位在坐标 x=20,y=20 处。坐标系的起点位于左上角。

当我们点击按钮时,会生成一个 wxEVT_COMMAND_BUTTON_CLICKED 事件。我们将该事件连接到 Button 类的 OnQuit 方法。因此当我们点击按钮时,就会调用 OnQuit 方法。

我们将键盘焦点设置在该按钮上。这样当我们按下回车键时,就会触发按钮的点击事件。

在 OnQuit 方法内部,我们调用了 Close 方法。这将终止我们的应用程序。

(补充说明:在 wxWidgets 框架中,调用 Close() 方法会触发 wxEVT_CLOSE_WINDOW 事件,该事件的默认处理程序会调用 wxWindow::Destroy() 来销毁窗口。对于应用程序的主窗口来说,这会进一步导致整个应用程序退出,前提是没有其他顶级窗口存在。这是 wxWidgets 应用程序的标准退出流程之一)

组件通信

了解组件如何在应用程序中进行通信非常重要。请看以下示例。

// Panels.h
#include <wx/wx.h>
#include <wx/panel.h> class LeftPanel : public wxPanel
{
public:
LeftPanel(wxPanel *parent); void OnPlus(wxCommandEvent & event);
void OnMinus(wxCommandEvent & event); wxButton *m_plus;
wxButton *m_minus;
wxPanel *m_parent;
int count; }; class RightPanel : public wxPanel
{
public:
RightPanel(wxPanel *parent); void OnSetText(wxCommandEvent & event); wxStaticText *m_text; }; const int ID_PLUS = 101;
const int ID_MINUS = 102; // Panels.cpp
#include <wx/stattext.h>
#include "Communicate.h" LeftPanel::LeftPanel(wxPanel * parent)
: wxPanel(parent, -1, wxPoint(-1, -1), wxSize(-1, -1), wxBORDER_SUNKEN)
{
count = 0;
m_parent = parent;
m_plus = new wxButton(this, ID_PLUS, wxT("+"),
wxPoint(10, 10));
m_minus = new wxButton(this, ID_MINUS, wxT("-"),
wxPoint(10, 60));
Connect(ID_PLUS, wxEVT_COMMAND_BUTTON_CLICKED,
wxCommandEventHandler(LeftPanel::OnPlus));
Connect(ID_MINUS, wxEVT_COMMAND_BUTTON_CLICKED,
wxCommandEventHandler(LeftPanel::OnMinus));
} void LeftPanel::OnPlus(wxCommandEvent & WXUNUSED(event))
{
count++; Communicate *comm = (Communicate *) m_parent->GetParent();
comm->m_rp->m_text->SetLabel(wxString::Format(wxT("%d"), count));
} void LeftPanel::OnMinus(wxCommandEvent & WXUNUSED(event))
{
count--; Communicate *comm = (Communicate *) m_parent->GetParent();
comm->m_rp->m_text->SetLabel(wxString::Format(wxT("%d"), count));
} RightPanel::RightPanel(wxPanel * parent)
: wxPanel(parent, wxID_ANY, wxDefaultPosition,
wxSize(270, 150), wxBORDER_SUNKEN)
{
m_text = new wxStaticText(this, -1, wxT("0"), wxPoint(40, 60));
} // Communicate.h
#include "Panels.h"
#include <wx/wxprec.h> class Communicate : public wxFrame
{
public:
Communicate(const wxString& title); LeftPanel *m_lp;
RightPanel *m_rp;
wxPanel *m_parent; }; // Communicate.cpp
#include "Communicate.h" Communicate::Communicate(const wxString& title)
: wxFrame(NULL, wxID_ANY, title, wxDefaultPosition, wxSize(290, 150))
{
m_parent = new wxPanel(this, wxID_ANY); wxBoxSizer *hbox = new wxBoxSizer(wxHORIZONTAL); m_lp = new LeftPanel(m_parent);
m_rp = new RightPanel(m_parent); hbox->Add(m_lp, 1, wxEXPAND | wxALL, 5);
hbox->Add(m_rp, 1, wxEXPAND | wxALL, 5); m_parent->SetSizer(hbox); this->Centre();
} // main.h
#include <wx/wx.h> class MyApp : public wxApp
{
public:
virtual bool OnInit();
}; // main.cpp
#include "main.h"
#include "Communicate.h" IMPLEMENT_APP(MyApp) bool MyApp::OnInit()
{ Communicate *communicate = new Communicate(wxT("Widgets communicate"));
communicate->Show(true); return true;
}

在我们的示例中,我们有两个面板:左侧面板和右侧面板。左侧面板有两个按钮,右侧面板有一个静态文本控件。这些按钮可以改变静态文本中显示的数字。现在的问题是:我们如何获取指向该静态文本控件的指针?

我们保存了指向 LeftPanel 父部件的指针,该父部件是一个 wxPanel 组件。

Communicate *comm = (Communicate *) m_parent->GetParent();

comm->m_rp->m_text->SetLabel(wxString::Format(wxT("%d"), count));

这两行代码是本示例中最关键的部分,它们展示了如何访问位于另一个面板上的静态文本控件。首先我们获取左右两个面板的父部件,这个父部件持有指向右侧面板的指针,而右侧面板又保存着指向静态文本控件的指针。在wxWidgets框架中,这种通过父窗口访问同级控件的模式是跨面板通信的典型实现方式。

至此,在wxWidgets教程的这一部分中,我们已经创建了一些简单的程序。

在Linux下使用wxWidgets进行跨平台GUI开发(三)的更多相关文章

  1. Linux下使用SSH、Crontab、Rsync三工具实现数据自动备份

    Linux下使用SSH.Crontab.Rsync三工具实现数据自动备份 作为网管人员大概都无一例外的经历过系统备份,尤其是重要系统的备份.重要数据库系统的备份工作.由于备份是个频繁而琐碎的工作,如何 ...

  2. Linux下套接字具体解释(三)----几种套接字I/O模型

    參考: 网络编程–IO模型演示样例 几种server端IO模型的简介及实现 背景知识 堵塞和非堵塞 对于一个套接字的 I/O通信,它会涉及到两个系统对象.一个是调用这个IO的进程或者线程,还有一个就是 ...

  3. Linux下的lds链接脚本简介(三)

    八. 内存区域命令 在默认情形下,连接器可以为section在程序地址空间内分配任意位置的存储区域.并通过输出section描述的> REGION属性显示地将该输出section限定于在程序地址 ...

  4. Linux下C ,C ++, Qt开发环境

    目录 Linux发行版的选择 安装常用的开发工具(这里针对C/C++/Qt) 安装openGL 中文输入法 安装sublime text 安装vscode apt-get常用命令 Qt环境 Qt常见问 ...

  5. 《使用wxWidgets进行跨平台程序开发》chap09——布局一个对话框

    ///////////////////////////////////////////////////////////////////////////// // Name: personalrecor ...

  6. Linux下串口与工业协议的开发

    1.串口通信原理 串口通信定义 串口通信:数据的串行传送方式.串口通信可分为同步通信与异步通信. 同步通信:按照软件识别同步字符来实现数据的发送和接收. 将许多字符组成一个信息组进行发送 要求发送时钟 ...

  7. 《使用wxWidgets进行跨平台程序开发》chap02——一个简单的应用程序

    // Name: minimal.cpp // Purpose: Minimal wxWidgets sample // Author: Julian Smart #include "wx/ ...

  8. Ubuntu 14.04 下使用微软的跨平台轻量级开发神器 Visual Studio Code

    因为 Visual Studio Code 不断更新,官方最新 v1.32 的 .deb 包已经不能用于 Ubuntu 14.04 直接安装了. 下载 v1.31 的 deb 包安装即可:https: ...

  9. Linux 下从头再走 GTK+-3.0 (三)

    之前我们为窗口添加了一个按钮,接下来让这个按钮丰富一点.并给窗口加上图标. 首先创建 example3,c 的源文件. #include <gtk/gtk.h> static void a ...

  10. Linux下移植pjsip,使用QT开发

    1.移植pjsip env:fedora14 arm-linuc-gcc:gcc version 4.5.1 (ctng-1.8.1-FA) #./configure \ CC=arm-linux-g ...

随机推荐

  1. GBJ 97-1987 水泥混凝土路面施工及验收规范(电子版)PDF 版本 下载

    本规范适用于新建和改建的公路 城市道路 厂矿道路和民航机场道面等就地浇筑的水泥混凝土路面的施工及验收 链接:https://pan.baidu.com/s/17t88jnEU6IrptmEWsyuN3 ...

  2. ISO9126

    ISO9126 软件质量模型是评价软件质量的国际标准,由6个特性和27个子特性组成.     中文名 软件质量模型 外文名 ISO9126 属    于 软件产品评价-质量特性 层    次 质量特性 ...

  3. halcon 入门教程(五) 缺陷检测

    原文作者:aircraft 原文链接:https://www.cnblogs.com/DOMLX/p/18785484 有兴趣可以多看其他的halcon教程 halcon 学习教程目录 本篇主要讲一些 ...

  4. Pandas中的选择

    1.选择 更多细节可见官方文档 import pandas as pd ID = [1,2,3] Name = ['Student_001','Student_002','Student_003'] ...

  5. 《机器人SLAM导航核心技术与实战》第1季:第11章_自主导航中的数学基础

    <机器人SLAM导航核心技术与实战>第1季:第11章_自主导航中的数学基础 视频讲解 [第1季]11.第11章_自主导航中的数学基础-视频讲解 [第1季]11.1.第11章_自主导航中的数 ...

  6. ro在xe10.3上的安装

    在学习研究RO. RO9.2.101.1295在xe10.3上安装遇到新问题.记录处理的办法: 没有采用执行exe安装的方法.而是采用复制源代码后编译安装. 1.把生成的bpl.dcp安装到默认目录, ...

  7. MCP (Model Context Protocol)初体验:企业数据与大模型融合初探

    简介 模型上下文协议(Model Context Protocol,简称MCP)是一种创新的开放标准协议,旨在解决大语言模型(LLM)与外部数据和工具之间的连接问题.它为AI应用提供了一种统一.标准化 ...

  8. MQTT协议发布和订阅的实现,一步步带你实现发布订阅服务。

    MQTT协议 MQTT协议是基于TCP传输协议之上的应用层协议,全程Message Queuing Telemetry Transport.主要用于物联网设备间的通信,在低带宽.不稳定网络环境下的优势 ...

  9. Python科学计算系列5—导数

    1.一元函数的导数 例1:求下列函数的导数 例2:求下列函数的50阶导数 代码如下: from sympy import * x = symbols('x') f1 = diff(tan(x)) f2 ...

  10. Model接口

    /** * Model接口 * 作用:将值存放到request对象 * * * @return */ @RequestMapping(value = "/testModle") p ...