簡體   English   中英

Qt:自定義小部件的多個布局

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM