2017-02-15 11 views
0

私のプログラムでは、2つの新しいQLineEditをgridLayoutに追加したいが、必要な場合にのみ追加する。 要件が満たされている場合は、QLineEditを追加します(例:lineEdit1)。別の名前はlineEdit2です。 しかし、解決策を探すとき、私は人がそれが不可能であるとか、配列を使うと言っているのを見ました。Qt - 変数名はどのように自動生成されますか?

私の質問は、どのようにQtデザイナーで行われるのでしょうか。 Qtデザイナに2つの同じ新しいアイテムを追加すると、ラベルは例えばlabellabel_2の名前になります。 ui _ **。hを生成すると、QLabel* labelQLabel* label_2が作成されます。

どうすればよいですか?

+0

'.ui'ファイルaおそらく[moc](https://doc.qt.io/qt-5/moc.html)を使ってC++コードを生成します。 – nwp

+1

@nwp実際には、 '.ui' - >' .h'コンパイルは['uic'](https://doc.qt.io/qt-5/uic.html)を使って行います。 – Angew

答えて

3

Qtのデザイナーは、XMLのようなファイルを使用してユーザーインターフェイス(UI)フォームのレイアウトを表現するためにファイルと呼ばれます。このファイルは、hirarchicalな方法で構造を記述します。

ビルドプロセス中に.uiファイルは、User Interface Compiler(uicまたはuic.exe)というツールで使用され、ソースコードが生成されます。ソースコードは、UIファイルに関連するクラスに含まれるヘッダーファイルに格納されます。

もちろんこれは手動で行うこともできます。このアプローチとあなたが達成したいことの違いは、意思決定の時間です。上述の手順は、コンパイル時間で知られている情報を使用します。プログラマーは、ソースコードを書く時にそのような変数があり、その名前を使ってアクセスできることを知っています。

ランタイムで決定したいようです。これはおそらく、人々が配列を使用することを提案している理由です。問題は、コンパイラが必要なオブジェクトの数を知ることができないことです。そのため、ポインタを格納する変数がないため、実行時に作成するオブジェクトへのポインタを格納するために、何らかの動的データ構造が必要です。

Qt(適切に使用される)はメモリ管理を担当するため、オブジェクトへのポインタは必ずしも必要ではないことに注意してください。一時的な使用にローカル変数を使用し、グリッドに空QGridLayoutがあると仮定すると、以下のような何かを行うことができ、GridLayoutのと呼ばれる:

bool cond1; 
bool cond2; 
int row = 0; 
int column = 0; 

/* set cond1 and cond2 based on your decision logic */ 

if(cond1) 
{ 
    QLineEdit *lineEdit = new QLineEdit("Text for LineEdit 1", this); 
    gridLayout->addWidget(lineEdit, row, column); 
    row++; 
    column++; 
} 

if(cond2) 
{ 
    QLineEdit *lineEdit = new QLineEdit("Text for LineEdit 2", this); 
    gridLayout->addWidget(lineEdit, row, column); 
    row++; 
    column++; 
} 

他の一般的な解決策は、(これは必ずしも可能ではないながら)静的にすべての可能なウィジェットを追加するだけで、次のように動的に表示を切り替えることです:あなたもQtのデザイナを使用することができますし、切り替えたいウィジェットの数が少ない場合に使用することができるアプローチで

bool cond1; 
bool cond2; 
lineEdit1->setVisible(cond1); /* Alternatevily show(), hide() */ 
lineEdit2->setVisible(cond2); 

。欠点は、それがうまくスケールされないということです。

+0

はい、それは私がやることですが、変数名は使用せず、gridLayoutの位置だけを使用します。 Qtデザイナーの説明に感謝します。 – Dinendal

+0

'std :: list'を使ってウィジェットを値で保持することもでき、' new'を使う必要はなく、他の種類のメモリ管理を自分で行うこともできます。 –

0

実行時にこれらの2つの要素をコードから動的に追加しますか? QDesignerを使ってUIフォームに追加したい場合は、デフォルトで非表示にしてから、他のいくつかのルールに基づいて表示しますか?

// widget.h

#ifndef WIDGET_H 
#define WIDGET_H 

#include <QWidget> 

namespace Ui { 
class Widget; 
} 

class Widget : public QWidget 
{ 
    Q_OBJECT 

public: 
    explicit Widget(QWidget *parent = 0); 
    ~Widget(); 

private: 
    Ui::Widget *ui; 
}; 

#endif // WIDGET_H 

// widget.cpp:ここ

あなたはUI-形で事前に定義された\ショーの特定の要素を非表示にすることができます方法の例です

#include "widget.h" 
#include "ui_widget.h" 

Widget::Widget(QWidget *parent) : 
    QWidget(parent), 
    ui(new Ui::Widget) 
{ 
    ui->setupUi(this); 

    bool requirement = true; 

    // hide elements based on flag 
    if(!requirement) 
    { 
     ui->lineEdit1->hide(); 
     ui->lineEdit2->hide(); 
    } 
    else 
    { 
     ui->lineEdit1->show(); 
     ui->lineEdit2->show(); 
    } 
} 

Widget::~Widget() 
{ 
    delete ui; 
} 

// main.cppに

#include "widget.h" 
#include <QApplication> 

int main(int argc, char *argv[]) 
{ 
    QApplication a(argc, argv); 
    Widget w; 
    w.show(); 

    return a.exec(); 
} 

// widget.ui

<?xml version="1.0" encoding="UTF-8"?> 
<ui version="4.0"> 
<class>Widget</class> 
<widget class="QWidget" name="Widget"> 
    <property name="geometry"> 
    <rect> 
    <x>0</x> 
    <y>0</y> 
    <width>400</width> 
    <height>300</height> 
    </rect> 
    </property> 
    <property name="windowTitle"> 
    <string>Widget</string> 
    </property> 
    <layout class="QGridLayout" name="gridLayout"> 
    <item row="0" column="0"> 
    <widget class="QLineEdit" name="lineEdit1"/> 
    </item> 
    <item row="0" column="1"> 
    <widget class="QLineEdit" name="lineEdit2"/> 
    </item> 
    </layout> 
</widget> 
<layoutdefault spacing="6" margin="11"/> 
<resources/> 
<connections/> 
</ui> 
+0

要素の数が比較的少ない場合、それは解決策になる可能性があります。私の例では、2つの要素についてしか言及していませんが、さらに多くの要素が存在する可能性があります.Un – Dinendal

+0

@Dinendalに多くの要素を追加するのが難しくなる可能性があるため、実行時に動的に要素を追加する必要があります。私の2番目の例を参照してください。 – Dmitriy

0

実行時にオブジェクトを動的に追加する場合は、オブジェクトの配列を使用して、初期化後にオブジェクトを処理できるようにする必要があります。

ここは簡単な例です。私はボタンのプレースホルダとしてUIフォームにQGridLayoutを追加し、動的に割り当てられた新しいオブジェクトで充填し、配列 'mButton'に追加してから、後で 'switchVisibility'スロットでこの配列を使用しました。

// widget.h

#ifndef WIDGET_H 
#define WIDGET_H 

#include <QWidget> 

namespace Ui { 
class Widget; 
} 

class QPushButton; 

class Widget : public QWidget 
{ 
    Q_OBJECT 

public: 
    explicit Widget(QWidget *parent = 0); 
    ~Widget(); 

private slots: 
    void switchVisibility(); 

private: 
    bool mFlag; 
    QList<QPushButton*> mButtons; 

    Ui::Widget *ui; 
}; 

#endif // WIDGET_H 

// widget.cpp

#include "widget.h" 
#include "ui_widget.h" 

#include <QPushButton> 

Widget::Widget(QWidget *parent) : 
    QWidget(parent), 
    mFlag(true), 
    ui(new Ui::Widget) 
{ 
    ui->setupUi(this); 

    int count = 0; 

    for(int row=0; row < 4; row++) { 
     for(int column = 0; column < 4; column++) { 
      // count button, for label 
      count++; 

      // create button 
      QPushButton* button = new QPushButton(this); 
      button->setText(QString::number(count)); 

      // add this button to grid layout in our gui 
      ui->mLayoutButtons->addWidget(button, row, column); 

      // put a pointer to button object into our array (QList) 
      // if we need to do something with it later 
      mButtons.append(button); 
     } 
    } 

    // connect hide button click to slot 
    QObject::connect(ui->mButtonHide, &QPushButton::clicked, this, &Widget::switchVisibility); 
} 

Widget::~Widget() 
{ 
} 

void Widget::switchVisibility() 
{ 
    // flip bool value 
    mFlag = !mFlag; 

    foreach (QPushButton* button, mButtons) { 
     button->setVisible(mFlag); 
    } 
} 

// widget.ui彼らは取ることによって、それを行う

<?xml version="1.0" encoding="UTF-8"?> 
<ui version="4.0"> 
<class>Widget</class> 
<widget class="QWidget" name="Widget"> 
    <property name="geometry"> 
    <rect> 
    <x>0</x> 
    <y>0</y> 
    <width>400</width> 
    <height>300</height> 
    </rect> 
    </property> 
    <property name="windowTitle"> 
    <string>Form</string> 
    </property> 
    <layout class="QVBoxLayout" name="verticalLayout"> 
    <item> 
    <layout class="QGridLayout" name="mLayoutButtons"/> 
    </item> 
    <item> 
    <widget class="QPushButton" name="mButtonHide"> 
    <property name="text"> 
     <string>Click me</string> 
    </property> 
    </widget> 
    </item> 
    </layout> 
</widget> 
<layoutdefault spacing="6" margin="11"/> 
<resources/> 
<connections/> 
</ui> 
関連する問題