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;
}
發佈了82 篇原創文章 · 獲贊 33 · 訪問量 8萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章