QT中使用嵌入窗口

需求

在主窗口中, 左边显示树形结构, 元素是不同类型的节点, 要求根据节点类型不同在主窗口右侧显示不同的控件内容

实现

这个功能在MFC中实现不是很方面, 但是在QT中比较简单

1. 在主界面中添加一个treeWidget

treeWidget放窗体showinfo中, 如图:
在这里插入图片描述
注意: 这里用一个Spacers顶着treeWidget, 有三个作用:

  1. 初始时树形控件的高度是铺满的;
  2. 如果这个窗口还要嵌入到别的窗口, 假如没有把showinfo窗体提前做布局, 那么在加入右侧的布局后, 即时用layout把左右部分布局, 拖动窗口边框时, 左右部分不会同步改变大小, 所以需要在设计ui时把showinfo窗体提前做布局;
  3. 做了布局以后, 如果没有Spacer顶着, 树形控件会充满窗体, 默认添加右侧布局后会看不到, 还需要代码中手动调整位置

2. 响应树形控件点击事件, 添加右侧布局

注意: 右侧布局的构造函数中hide(), 否则界面一加载就显示, 不满足需求
代码:

void OrgShowAllDeviceDlg::on_treeAllDevices_itemClicked(QTreeWidgetItem *item, int column)
{
    if (item->text(column) == "编码器")
    {
        _mgrEncoder->move(ui->treeAllDevices->width(), 0);
        _mgrEncoder->show();
        QLayout *layout = this->layout();
        layout->removeItem(ui->horizontalSpacer);
//        QHBoxLayout *layout = new QHBoxLayout(this);
//        layout->addWidget(ui->treeAllDevices);
        layout->addWidget(_mgrEncoder);
        setLayout(layout);
    }
}

右侧窗体如图:
在这里插入图片描述

3. 效果

  • 打开主窗体, 加载showinfo
    在这里插入图片描述
  • 点击shouinfo的树形控件
    在这里插入图片描述

4. 改进

固定右侧布局的高度

现在上下拖动改变窗体的时候, 右侧布局中每行间隔变很大, 可以设定最大最小高度, 加一个layoutSpacer顶着它, 代码如下:

void OrgShowAllDeviceDlg::on_treeAllDevices_itemClicked(QTreeWidgetItem *item, int column)
{
    if (item->text(column) == "编码器")
    {
        _mgrEncoder->move(ui->treeAllDevices->width(), 0);
        _mgrEncoder->show();
        QVBoxLayout *vlayout = new QVBoxLayout(this);
        vlayout->addWidget(_mgrEncoder);
        vlayout->addStretch(1);
        QHBoxLayout *layout = (QHBoxLayout*)(this->layout());
        layout->removeItem(ui->horizontalSpacer);
        layout->addLayout(vlayout);
        setLayout(layout);
    }
}

效果:
在这里插入图片描述

多个右侧布局的切换

比如右侧的编码器解码器的右侧布局不同, 并且要切换显示
在右侧布局中加入他们并隐藏, 这段代码在主窗体showinfo的构造函数中实现:

OrgShowAllDeviceDlg::OrgShowAllDeviceDlg(QWidget *parent) : QWidget(parent), ui(new Ui::ShowAllDevices)
{
    ui->setupUi(this);
	_mgrEncoder = new ManageEncoderDlg(this);//编码器
    _mgrEncoder->move(ui->treeAllDevices->width(), 0);
    _mgrDecoder = new ManageDecoderDlg(this);//解码器
    _mgrDecoder ->move(ui->treeAllDevices->width(), 0);

    QVBoxLayout *vlayout = new QVBoxLayout(this);
    vlayout->addWidget(_mgrEncoder);
    vlayout->addWidget(_mgrDecoder );
    vlayout->addStretch(1);
    QHBoxLayout *layout = (QHBoxLayout*)(this->layout());
    layout->removeItem(ui->horizontalSpacer);
    layout->addLayout(vlayout);
    setLayout(layout);
}

此时, 树形控件的点击代码简化如下:

void OrgShowAllDeviceDlg::on_treeAllDevices_itemClicked(QTreeWidgetItem *item, int column)
{
    if (item->text(column) == "编码器")
    {
        _mgrEncoder->show();
        _mgrDecoder ->hide();

    }
    if (item->text(column) == "解码器")
    {
        _mgrEncoder->hide();
        _mgrDecoder ->show();
    }
}

运行效果如下:
点击编码器:
在这里插入图片描述
切换到解码器:
在这里插入图片描述
切换并不会影响控件内的内容, 所以可以给控件映射sqlmodle, 进行数据库操作

使用UI文件

因为没有找到嵌入对话框的办法(MFC的做法), 所以利用布局的addWidget加入了分块的Widget
Widget的设计文件是ui文件, 需要关联一个class才能使用
关联的方式有两种

第一种非常简单, 添加新文件时, 选择Qt设计师界面类

![在这里插入图片描述](https://img-blog.csdnimg.cn/2019081610542340.png)
界面模板选择`Widget`
![在这里插入图片描述](https://img-blog.csdnimg.cn/20190816105449137.png)
![在这里插入图片描述](https://img-blog.csdnimg.cn/20190816105507158.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2Jsd2lubmVy,size_16,color_FFFFFF,t_70)
输入类名和界面文件名下一步, 完成

第二种方法是如果只有ui文件, 需要一个class关联

1. 项目中添加该ui文件, **编译项目**
2. 成功编译后, 在构建目录下生成`ui_ui文件名.h`
3.  新建一个c++类, 父类选择`QtWidget`
 ![在这里插入图片描述](https://img-blog.csdnimg.cn/20190816105857633.png)
 4. 参照Qt默认的代码生成
 	1. 在`.h`中增加:
namespace Ui {
class ui文件名;
}
		增加:
private:
   Ui::OrgMainWindow *ui;
    2. 在.cpp中增加:
OrgMainWindow::OrgMainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::ui文件名)
{
    ui->setupUi(this);

    _showAllDeviceDlg = new OrgShowAllDeviceDlg(this);
    on_actShowAllDevice_triggered();
}

OrgMainWindow::~OrgMainWindow()
{
    delete ui;
}
  • 3
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值