Qtのレイアウト管理とダイアログ実装テクニック

Qtウィジェットレイアウトの設計手法

Qtフレームワークでは、QLayoutを基底とするレイアウト管理システムが提供されています。主なレイアウトクラスの継承関係は以下の通りです:

クラス 基底クラス 派生クラス
QBoxLayout QLayout QHBoxLayout, QVBoxLayout
QGridLayout QLayout なし
QStackedLayout QLayout QStackedWidget内蔵

グリッドレイアウトの実装例

従業員情報フォームを構築する場合、QGridLayoutを活用した実装が効果的です:

#include <QApplication>
#include <QDialog>
#include <QGridLayout>
#include <QComboBox>

class EmployeeForm : public QDialog {
    Q_OBJECT
public:
    explicit EmployeeForm(QWidget *parent = nullptr);
private:
    QGridLayout *mainLayout;
    QLineEdit *employeeIdField;
    QComboBox *departmentSelector;
};

EmployeeForm::EmployeeForm(QWidget *parent) 
    : QDialog(parent) 
{
    setWindowTitle(tr("従業員登録フォーム"));
    
    // フィールドの初期化
    employeeIdField = new QLineEdit;
    departmentSelector = new QComboBox;
    departmentSelector->addItems({tr("開発部"), tr("営業部"), tr("人事部")});
    
    // レイアウト構築
    mainLayout = new QGridLayout(this);
    mainLayout->addWidget(new QLabel(tr("社員番号:")), 0, 0);
    mainLayout->addWidget(employeeIdField, 0, 1);
    mainLayout->addWidget(new QLabel(tr("所属部署:")), 1, 0);
    mainLayout->addWidget(departmentSelector, 1, 1);
    
    // 余白の調整
    mainLayout->setColumnStretch(1, 1);
    mainLayout->setRowMinimumHeight(2, 20);
}

タブ型インターフェースの実装

QStackedWidgetは複数のウィジェットをスタック状に管理し、動的なコンテンツ切り替えを実現します。実装のポイントはQListWidgetとの連携です:

QStackedWidget *contentStack = new QStackedWidget;
QListWidget *navPanel = new QListWidget;

// コンテンツの追加
contentStack->addWidget(new DepartmentOverview(tr("開発部概要")));
contentStack->addWidget(new DepartmentOverview(tr("営業部概要")));

// ナビゲーションの設定
navPanel->addItem(tr("開発部"));
navPanel->addItem(tr("営業部"));

// クリックイベントのバインディング
connect(navPanel, &QListWidget::currentRowChanged,
        contentStack, &QStackedWidget::setCurrentIndex);

// メインレイアウト
QHBoxLayout *layout = new QHBoxLayout(this);
layout->addWidget(navPanel, 1);
layout->addWidget(contentStack, 3);

ダイアログコンポーネントの実践的利用

ファイル操作ダイアログ

QFileDialogを用いたファイル選択処理では、ファイル属性の取得が重要なポイントです:

void FileProcessor::selectFile() {
    QString filePath = QFileDialog::getOpenFileName(
        this, 
        tr("ファイル選択"), 
        QDir::homePath(),
        tr("テキストファイル (*.txt);;すべてのファイル (*.*)")
    );
    
    if (!filePath.isEmpty()) {
        QFileInfo fileInfo(filePath);
        fileSizeLabel->setText(
            tr("%1 KB").arg(fileInfo.size() / 1024)
        );
        filePreview->loadContent(filePath);
    }
}

カスタムメッセージボックスの構築

標準のQMessageBoxを拡張して、独自のアクションボタンを実装する手法:

int CustomMessageBox::showConfirmation(const QString &text) {
    QMessageBox msg(this);
    msg.setWindowTitle(tr("確認"));
    msg.setText(text);
    msg.setIcon(QMessageBox::Question);
    
    QPushButton *confirmBtn = msg.addButton(
        tr("実行"), QMessageBox::AcceptRole
    );
    QPushButton *cancelBtn = msg.addButton(
        tr("中止"), QMessageBox::RejectRole
    );
    
    msg.setDefaultButton(confirmBtn);
    msg.exec();
    
    return (msg.clickedButton() == confirmBtn) ? 1 : 0;
}

ドッキング可能なUIコンポーネント

QDockWidgetを活用した柔軟なインターフェース設計では、以下の設定が重要です:

void MainWindow::setupDockWidgets() {
    // ドックウィジェットの作成
    QDockWidget *toolDock = new QDockWidget(tr("ツールパネル"), this);
    toolDock->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea);
    
    // コンテンツの設定
    QWidget *toolContent = new QWidget;
    QVBoxLayout *toolLayout = new QVBoxLayout(toolContent);
    toolLayout->addWidget(new QPushButton(tr("フォーマット変換")));
    toolLayout->addWidget(new QPushButton(tr("データエクスポート")));
    toolDock->setWidget(toolContent);
    
    // ドッキング設定
    addDockWidget(Qt::RightDockWidgetArea, toolDock);
    toolDock->setFeatures(
        QDockWidget::DockWidgetMovable | 
        QDockWidget::DockWidgetFloatable
    );
}

タグ: QGridLayout QStackedWidget QDockWidget QFileDialog QMessageBox

6月2日 16:55 投稿