[英]Qt: Multiple layouts for a custom widget
我正在开发一个由其他小部件(按钮、标签、查看器等)组成的自定义小部件,它将成为其他项目中的一个模块。 为这个自定义小部件设置多个布局很重要。
布局将根据一些动态确定的因素而改变,例如作为一部分的应用程序(例如,对于 X 应用程序,我们希望事物垂直排列,或者我们希望 Z 小部件紧挨着 M 小部件而不是另一个小部件下方)以及根据检测到的功能(如果未检测到硬件 X,则隐藏 A、B、C 小部件)。
到现在为止,我在 Designer Form 中只有一个布局,我会在运行中以编程方式对小的重新排列进行一些修改。这不再可行,因为在某些应用程序中我们需要完全不同的布局。
所以,总而言之,我们有固定数量的小部件,但我们希望根据一些动态确定的因素进行不同的重新排列和可见性。
处理这种情况的正确方法是什么?
到目前为止我想到的解决方案:
创建多个 .ui 文件并使用QUiLoader动态加载我需要的文件
纯粹以编程方式创建布局
使用堆叠的小部件创建单个 .ui 文件,每个页面将是不同的布局。 切换布局时,“活动”布局的小部件将由指针分配。
我建议选项#2,以及一种干净的实现方式。
如果您的自定义小部件只是带有一些子小部件的 QWidget 子类,则您可以添加一个受保护的虚拟方法,该方法只负责布置子小部件,以及一个静态工厂方法来实例化正确的子类,具体取决于运行时配置选项。
只需将子实例作为受保护的成员,以便子类可以访问它们,添加受保护的customlayout
纯虚方法、公共initialize
方法和静态create
方法。 在构造函数中,只需设置子小部件并连接信号和插槽(不要在意孩子的位置和可见性,在这里)。 一旦调用, initialize
方法会将虚函数返回的布局设置为自定义小部件布局。
class CustomWidget : public QWidget
{
Q_OBJECT
protected:
virtual QLayout * customlayout() = 0;
QLabel a;
QLineEdit b;
QPushButton c;
public:
CustomWidget(QWidget * p) : QWidget(p)
{
a.setText("Text:");
c.setText("Ok");
//setup signals/slot etc.
}
void initialize()
{
setLayout(customlayout());
}
static CustomWidget * create();
};
几个可能的实现:
#include <QHBoxLayout>
class XCustomWidget : public CustomWidget
{
public:
XCustomWidget() : CustomWidget(nullptr){}
protected:
QLayout * customlayout() override
{
QHBoxLayout * l = new QHBoxLayout();
l->addWidget(&a);
l->addWidget(&b);
l->addWidget(&c);
return l;
}
};
#include <QVBoxLayout>
class YCustomWidget : public CustomWidget
{
public:
YCustomWidget() : CustomWidget(nullptr){}
protected:
QLayout * customlayout() override
{
QVBoxLayout * l = new QVBoxLayout();
l->addWidget(&a);
l->addWidget(&b);
c.setVisible(false);
l->addStretch(1);
return l;
}
};
一个可能的工厂实现:
CustomWidget *CustomWidget::create()
{
//read configuration ...
if(isApplicationX)
{
return new XCustomWidget();
}
if(isApplicationY)
{
return new YCustomWidget();
}
}
和实例化(例如在表单构造函数中):
CustomWidget * w = CustomWidget::create();
w->initialize();
layout()->addWidget(w);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.