问题描述
我有一个不同宽度的圆圈。我创建了一个由 Screen1ViewBase 类继承的子类,以访问 WidthChange.cpp 中的“circlewidth”。我可以访问“circlewidth”。但是我无法在 Screen1View.cpp 中调用 Change 函数,因为它不是静态的。我将 Change 函数设为静态,但这次我无法访问“circlewidth”和 Screen1View 的另一个成员。
#ifndef SCREEN1VIEWBASE_HPP
#define SCREEN1VIEWBASE_HPP
#include <gui/common/FrontendApplication.hpp>
#include <mvp/View.hpp>
#include <gui/screen1_screen/Screen1Presenter.hpp>
#include <touchgfx/widgets/Box.hpp>
#include <touchgfx/widgets/canvas/Circle.hpp>
#include <touchgfx/widgets/canvas/PainterRGB565.hpp>
class Screen1ViewBase : public touchgfx::View<Screen1Presenter>
{
public:
Screen1ViewBase();
virtual ~Screen1ViewBase() {}
virtual void setupScreen();
protected:
FrontendApplication& application() {
return *static_cast<FrontendApplication*>(touchgfx::Application::getInstance());
}
/*
* Member Declarations
*/
touchgfx::Box __background;
touchgfx::Box Box1;
touchgfx::Circle circlewidth;
touchgfx::PainterRGB565 circlewidthPainter;
private:
/*
* Canvas Buffer Size
*/
static const uint16_t CANVAS_BUFFER_SIZE = 7200;
uint8_t canvasBuffer[CANVAS_BUFFER_SIZE];
};
#endif // SCREEN1VIEWBASE_HPP
#ifndef SCREEN1VIEW_HPP
#define SCREEN1VIEW_HPP
#include <gui_generated/screen1_screen/Screen1ViewBase.hpp>
#include <gui/screen1_screen/Screen1Presenter.hpp>
class Screen1View : public Screen1ViewBase
{
public:
Screen1View();
virtual ~Screen1View() {}
virtual void setupScreen();
virtual void tearDownScreen();
virtual void handleTickEvent();
protected:
int linewidthLimit;
float circleWidthChangeFactor;
};
#endif // SCREEN1VIEW_HPP
#include <gui/screen1_screen/Screen1View.hpp>
#include <gui/WidthChange.hpp>
Screen1View::Screen1View()
{
}
void Screen1View::setupScreen()
{
Screen1ViewBase::setupScreen();
}
void Screen1View::tearDownScreen()
{
Screen1ViewBase::tearDownScreen();
}
void Screen1View::handleTickEvent()
{
WidthChange::Change();
}
这是我的类声明
#ifndef WIDTHCHANGE_HPP
#define WIDTHCHANGE_HPP
#include <gui/screen1_screen/Screen1View.hpp>
#include <gui_generated/screen1_screen/Screen1ViewBase.hpp>
class WidthChange : public Screen1View
{
public:
static void Change();
};
#endif
这是声明 Change() 函数的地方
#include <gui/WidthChange.hpp>
#include <gui_generated/screen1_screen/Screen1ViewBase.hpp>
#include <gui/screen1_screen/Screen1View.hpp>
#include <gui/screen1_screen/Screen1Presenter.hpp>
void WidthChange::Change()
{
float currenTrad;
float linewidth;
circlewidth.invalidate();
circlewidth.geTradius(currenTrad);
if (currenTrad >= linewidthLimit)
{
circleWidthChangeFactor = -0.25;
}
else if (currenTrad<= 15)
{
circleWidthChangeFactor = 0.25;
}
currenTrad = currenTrad + circleWidthChangeFactor;
circlewidth.seTradius(currenTrad);
circlewidth.getlinewidth(linewidth);
circlewidth.setlinewidth(linewidth + 2 * (circleWidthChangeFactor * (-1)));
circlewidth.invalidate();
}
我知道有很多关于它的事情,但我想知道是否有办法在调用 Change 函数时访问整个 Screen1View 成员和 Screen1ViewBase 成员。
解决方法
c++中的静态成员函数只能访问静态成员数据,或者其他静态成员函数。 Screen1View 可以访问静态函数。
如果您的回调需要进行一些复杂的 ui 设置/计算,那么拥有这样的中间类可能是一个好主意。但是在这里创建 Screen1View 的子类是没有意义的,因为它的类型 View
这不是你想要的(也有很多包袱)。
如果您需要访问 Screen1View
中的成员,您可以定义一个具有非静态成员的类,并使用指向父级的指针来构造它,而不是使用继承,但为成员提供对其父级的访问权限真的不推荐。
相反,我建议在类定义中使用更通用的函数。例如(人为的例子)。这将允许您在 Views 回调处理程序中保留对代码的清晰描述,而不是将其全部隐藏在 helperclass 中的某个函数中。这些函数可以是静态的。
void HelperClass::setCircleRadius(touchgfx::Circle* circle,float radius)
{
circle.setRadius(radius);
circle.invalidate();
}
如果我们现在假设 CircleHelper
更完整,则视图中的处理程序代码将如下所示并且更具可读性:
void Screen1View::someCallback()
{
CircleHelper::setRadius(&myCircle,someValue);
//More calls here to do what you want. LineHelper::..
//But now the code communicates only what it needs to.
//Most often "invalidate" is expected,so we don't want to be
//reading 100 occurrences of invalidate(); clutter
}
在 TouchGFX 设计器为您生成 ui 代码之前,我严重依赖静态帮助程序类来进行繁琐的设置,这些设置通常只会使 setupScreen()
变得混乱并且没有向任何人提供有价值的信息。