【QT】一个界面中嵌入其它界面(三)

在 Qt 中,通过 UI 设计 或 代码布局 实现界面 A 中同时显示界面 B 和 C,并精确指定它们的位置,可以通过以下两种方式实现。以下是详细步骤和完整代码:


方法 0:使用 Qt Designer 可视化布局

通过 Qt Designer 拖拽控件并设置布局,直观控制子界面的位置。

步骤
  1. 创建子界面 B 和 C:

    • 新建两个自定义 QWidget 类(如 WidgetB 和 WidgetC),并在 Qt Designer 中设计它们的 UI。
    • 保存为 .ui 文件(例如 widgetb.ui 和 widgetc.ui)。
  2. 提升为自定义控件:

    • 在主界面 A 的 .ui 文件中,拖入两个 QGridLayout 控件。
    • 两个控件分别重命名为 WidgetB_gl 和 WidgetC_gl。
  3. 设置布局或绝对位置:

cpp 复制代码
WidgetB* widgetb= new WidgetB(this);
WidgetC* widgetc= new WidgetC(this);

ui->WidgetB_gl->addWidget(widgetb); 
ui->WidgetC_gl->addWidget(widgetc);

方法 1:使用 Qt Designer 可视化布局

通过 Qt Designer 拖拽控件并设置布局,直观控制子界面的位置。

步骤
  1. 创建子界面 B 和 C:

    • 新建两个自定义 QWidget 类(如 WidgetB 和 WidgetC),并在 Qt Designer 中设计它们的 UI。
    • 保存为 .ui 文件(例如 widgetb.ui 和 widgetc.ui)。
  2. 提升为自定义控件:

    • 在主界面 A 的 .ui 文件中,拖入两个 QWidget 控件。
    • 右键点击这两个 QWidget,选择 Promote to... ,分别提升为 WidgetB 和 WidgetC。
  3. 设置布局或绝对位置:

    • 使用布局管理器 :将界面 B 和 C 拖入 QGridLayout 或 QHBoxLayout/QVBoxLayout,调整行列位置。
    • 绝对位置 :取消布局管理器,直接拖拽调整 WidgetB 和 WidgetC 的位置和大小。

方法 2:纯代码实现布局

通过代码动态创建子界面并添加到指定位置。

完整代码示例
1. 子界面 B 和 C 的定义
cpp 复制代码
// WidgetB.h
#ifndef WIDGETB_H
#define WIDGETB_H

#include <QWidget>
#include <QLabel>
#include <QVBoxLayout>

class WidgetB : public QWidget {
    Q_OBJECT
public:
    explicit WidgetB(QWidget* parent = nullptr);
};

#endif // WIDGETB_H

// WidgetB.cpp
#include "WidgetB.h"

WidgetB::WidgetB(QWidget* parent) : QWidget(parent) {
    QLabel* label = new QLabel("子界面 B", this);
    label->setAlignment(Qt::AlignCenter);
    QVBoxLayout* layout = new QVBoxLayout(this);
    layout->addWidget(label);
    setStyleSheet("background-color: #FFCCCC;"); // 粉色背景
}
cpp 复制代码
// WidgetC.h
#ifndef WIDGETC_H
#define WIDGETC_H

#include <QWidget>
#include <QLabel>
#include <QVBoxLayout>

class WidgetC : public QWidget {
    Q_OBJECT
public:
    explicit WidgetC(QWidget* parent = nullptr);
};

#endif // WIDGETC_H

// WidgetC.cpp
#include "WidgetC.h"

WidgetC::WidgetC(QWidget* parent) : QWidget(parent) {
    QLabel* label = new QLabel("子界面 C", this);
    label->setAlignment(Qt::AlignCenter);
    QVBoxLayout* layout = new QVBoxLayout(this);
    layout->addWidget(label);
    setStyleSheet("background-color: #CCFFCC;"); // 绿色背景
}

2. 主界面 A 的实现
cpp 复制代码
// WidgetA.h
#ifndef WIDGETA_H
#define WIDGETA_H

#include <QWidget>
#include <QGridLayout>
#include "WidgetB.h"
#include "WidgetC.h"

class WidgetA : public QWidget {
    Q_OBJECT
public:
    explicit WidgetA(QWidget* parent = nullptr);
};

#endif // WIDGETA_H

// WidgetA.cpp
#include "WidgetA.h"

WidgetA::WidgetA(QWidget* parent) : QWidget(parent) {
    // 创建网格布局
    QGridLayout* gridLayout = new QGridLayout(this);

    // 创建子界面 B 和 C,并指定父对象为 A
    WidgetB* widgetB = new WidgetB(this);
    WidgetC* widgetC = new WidgetC(this);

    // 将 B 和 C 添加到网格布局的指定位置
    gridLayout->addWidget(widgetB, 0, 0);  // 第 0 行,第 0 列(左上角)
    gridLayout->addWidget(widgetC, 1, 1);  // 第 1 行,第 1 列(右下角)

    // 设置布局边距和间距
    gridLayout->setContentsMargins(20, 20, 20, 20);
    gridLayout->setSpacing(15);

    // 设置主界面背景色
    setStyleSheet("background-color: #F0F0F0;");
    resize(600, 400); // 初始窗口大小
}

3. 主函数
cpp 复制代码
// main.cpp
#include <QApplication>
#include "WidgetA.h"

int main(int argc, char* argv[]) {
    QApplication app(argc, argv);
    WidgetA widgetA;
    widgetA.setWindowTitle("多子界面布局示例");
    widgetA.show();
    return app.exec();
}

效果说明

  • 布局管理器控制:

    • 子界面 B 位于左上角(第 0 行第 0 列),子界面 C 位于右下角(第 1 行第 1 列)。
    • 窗口缩放时,子界面会按布局比例自动调整位置和大小。
  • 自定义样式:

    • 子界面 B 为粉色背景,子界面 C 为绿色背景,主界面为灰色背景,便于观察位置。

扩展:手动指定绝对坐标

如果希望子界面位置固定(不随窗口缩放变化),可以使用 setGeometry:

cpp 复制代码
// WidgetA.cpp(替代布局代码)
WidgetA::WidgetA(QWidget* parent) : QWidget(parent) {
    // 创建子界面 B 和 C
    WidgetB* widgetB = new WidgetB(this);
    WidgetC* widgetC = new WidgetC(this);

    // 手动设置位置和大小
    widgetB->setGeometry(50, 50, 200, 150);   // (x, y, width, height)
    widgetC->setGeometry(300, 200, 200, 150);

    // 设置主界面背景色和大小
    setStyleSheet("background-color: #F0F0F0;");
    resize(600, 400);
}

关键点总结

  1. 父子关系 :确保子界面(B 和 C)的父对象为 WidgetA(通过构造函数或 setParent)。
  2. 布局管理器 :
    • 使用 QGridLayout、QHBoxLayout 或 QVBoxLayout 实现动态布局。
    • 通过行列索引(如 gridLayout->addWidget(widget, row, col))精确控制位置。
  3. 绝对坐标 :
    • 使用 setGeometry(x, y, width, height) 或 move() + resize() 固定位置。
    • 需在窗口大小变化事件(resizeEvent)中手动调整子界面位置。
  4. 样式调试 :通过 setStyleSheet 设置背景色,直观观察子界面位置。

扩展场景

  • 动态添加/移除子界面 :通过按钮点击事件调用 addWidget() 或 removeWidget()。
  • 交互通信:在子界面中定义信号,主界面中绑定槽函数,实现数据传递。
  • 复杂布局 :嵌套使用多种布局管理器(如将 QHBoxLayout 嵌入 QGridLayout)。

通过上述方法,可以灵活地在 Qt应用中实现多子界面的精确布局。

相关推荐
呆呆虫1211 小时前
用 orjson 加速 SerpBase 响应解析:基准对比与注意事项
开发语言·php
心疼你的一切11 小时前
Python自动发邮件实战定时发报表
大数据·开发语言·python
Wang's Blog12 小时前
Java 项目实战:交友项目 - 用户体系集成总结
java·开发语言·交友
中科三方13 小时前
IPv6检测常见问题:AAAA记录检测不通过是什么原因?
开发语言·php
沫璃染墨13 小时前
从零入门计算机网络系列(十一):HTTP协议进阶——从重定向原理到GET/POST与Fiddler抓包
linux·服务器·开发语言·网络·c++·tcp/ip·html
刚入门的大一新生14 小时前
Linux-线程互斥
java·开发语言
香芋芋圆14 小时前
iD-editor 详解|OSM官方在线编辑器,基于D3.js的轻量地图编辑器
开发语言·javascript·编辑器
蓝祁子yoky14 小时前
Qt学习日记 Day13:网络编程(一)-TCP基础与Socket实战
网络·qt·学习
小熊恋旧15 小时前
Python 面向对象编程:方法、属性、继承与多态详解
开发语言·python
云边云科技_云网融合15 小时前
面向汽车零部件制造业场景的解决方案 | 70 秒:一台车下线的时间里,藏着五张网
开发语言·汽车·php