wxWidgets项目的最佳开发流程

原文地址:李浩的博客 lihaohello.top


近期,对wxWidgets框架进行了断断续续的摸索,基本确定将它作为今后开发个人桌面小工具的首选技术,并打算对其设计逻辑和源代码进行适当探索。
上一篇关于wxWidgets的文章介绍了如何安装编译源代码、引入props配置文件,从而创建一个可运行的wxWidgets项目。但在实际项目开发过程中,开发环境配置只是第一步,要保证开发效率,还需要一整套流程来应对前端界面和后端业务交互迭代的情况。
推荐使用wxFormBuilder进行wxWidgets项目的前端界面设计,具体的使用方式有多种:①直接使用该工具生成的C++代码;②直接使用该工具生成的XRC资源文件;③使用XRC资源文件编译得到的C++代码。
以上第②种方式生成的程序在运行时必须附带XRC资源文件,而采用第①、③种方式时,资源文件可以嵌入程序,发行更方便。另外,使用wxFormBuilder生成代码时,最好不要手动调整这些生成代码,防止前端界面更新迭代时覆盖手动调整的内容。
推荐采用方式③进行前端界面开发,在此基础上探索wxWidgets项目的最佳开发流程。本文示例代码也可以作为wxWidgets项目的开发模板。

基本项目配置

  • 新建VC++空项目
  • 设置“配置属性——链接器——系统——子系统”为“窗口 (/SUBSYSTEM:WINDOWS)”
  • 导入wxWidgets-3.2.4\wxwidgets.props项目配置文件,无需手动设置头文件路径和依赖库
  • 新建main.cpp文件,定义wxApp的派生类(程序启动类)
#include "wx/wx.h"

class MyApp :public wxApp {
public:
	virtual bool OnInit();
};
wxIMPLEMENT_APP(MyApp);

bool MyApp::OnInit() {
	if (!wxApp::OnInit())
		return false;
	return true;
}

wxFormBuilder设计GUI

  • 新建wxFormBuilder项目,设置文件名,设置生成XRC文件
    image.png
  • 设计窗体
    image.png
  • 生成XRC代码

将XRC编译成C++代码

wxWidgets源码安装路径下有XRC编译器源码(wxWidgets-3.2.4\utils\wxrc\),需要手动编译,编译完成之后得到wxrc.exe可执行文件。

  • wxrc.exe基本用法
    • wxrc.exe -c:将XRC编译成cpp源文件,用来替代XRC文件
    • wxrc.exe -c -e:除了生成上述cpp源文件外,还可以生成额外的头文件,头文件中已经获得了各控件的指针变量。
  • 编译XRC:wxrc.exe -c -e resource.xrc
  • 项目生成时自动编译XRC:设置xrc文件的配置属性,添加自定义生成工具,这样项目重新生成时可根据文件是否更新来选择是否重新编译xrc文件。
    命令行:D:\wxWidgets-3.2.4\utils\wxrc\vc_x64_mswu\wxrc.exe -c -e %(FullPath) .%(Filename).xrc
    输出:%(Filename).h;%(Filename).cppimage.png

引入C++代码并扩展窗体类

从xrc文件编译而来的头文件和源文件中不包含事件绑定、事件处理等代码,如果开发者直接在生成代码中添加这些逻辑,这些手动修改的内容会在下次重新编译XRC文件后被覆盖,因此禁止手动修改生成代码,可在新的代码文件中继承生成代码中的窗体类来添加这些额外逻辑。

#pragma once
#include "wx/wx.h"
#include "wx/xrc/xmlres.h"
#include "resource.h"

class MyDialog2Derived :public MyDialog2
{
public:
	MyDialog2Derived() :MyDialog2(nullptr) {
		// 绑定按钮事件
		m_btnAdd->Bind(wxEVT_BUTTON, &MyDialog2Derived::OnAdd, this);
		m_btnSubtract->Bind(wxEVT_BUTTON, &MyDialog2Derived::OnSubtract, this);
		m_btnExit->Bind(wxEVT_BUTTON, &MyDialog2Derived::OnExit, this);

		m_button7->Bind(wxEVT_BUTTON, &MyDialog2Derived::OnExit, this);
	}

	/// @brief 加运算
	/// @param event 
	void OnAdd(wxCommandEvent& event) {
		double num1, num2;
		if (!m_textNum1->GetValue().ToDouble(&num1) || !m_textNum2->GetValue().ToDouble(&num2))
		{
			m_textRes->SetValue("");
			wxMessageBox("操作数非法,请重新输入!", "温馨提示", wxOK | wxICON_ERROR);
			return; 
		}

		double res = num1 + num2;
		m_textRes->SetValue(wxString::Format("%.3f",res));
	}

	/// @brief 减运算
	/// @param event 
	void OnSubtract(wxCommandEvent& event) {
		double num1, num2;
		if (!m_textNum1->GetValue().ToDouble(&num1) || !m_textNum2->GetValue().ToDouble(&num2))
		{
			m_textRes->SetValue("");
			wxMessageBox("操作数非法,请重新输入!", "温馨提示", wxOK | wxICON_ERROR);
			return;
		}

		double res = num1 - num2;
		m_textRes->SetValue(wxString::Format("%.3f", res));
	}

	/// @brief 退出事件
	/// @param event 
	void OnExit(wxCommandEvent& event) {
		Close(true);
	}
};

同时,要更新MyApp类的内容:加载资源、创建顶层窗体

#include "wx/wx.h"
#include "wx/xrc/xmlres.h"

#include "resource.h"
#include "MyDialog2Derived.h"

class MyApp :public wxApp {
public:
	virtual bool OnInit();

private:
	MyDialog2Derived* dlg;

public:
};
wxIMPLEMENT_APP(MyApp);

bool MyApp::OnInit() {
	if (!wxApp::OnInit())
		return false;

	wxXmlResource::Get()->InitAllHandlers();
	InitXmlResource();

	dlg = new MyDialog2Derived();
	dlg->ShowModal();
	dlg->Destroy();

	return true;
}

将变化点限制在GUI设计

流程总结:使用wxFormBuilder设计界面生成xrc文件;将xrc编译成C++头文件和源文件;引用生成的C++代码,派生其窗体类,在子类中实现窗体的事件处理逻辑;在App类的OnInit()函数中创建子类实例,运行之。
在业务开发过程中,当前端界面GUI发生变化时,只需要在wxFormBuilder中重新生成xrc文件,然后重新编译项目即可。这种xrc自动编译、派生类机制将变化点限值在GUI设计,避免了工具自动生成代码和手动调整代码之间的矛盾性,从而保证了开发工作的连贯性。


原文地址:李浩的博客 lihaohello.top

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值