QT 自定义界面布局要诀
1. 问题:有三个UI 子界面在一个主界面UI 上组合,那么三个子界面需要从主界面传递QSize子区域大小吗?
如下:
MonitorWnd::MonitorWnd(QSzie size, QWidget* parent)
:ViewBaseWnd(parent){setFixedSize(size);
}
实践所得:不需要设置大小,只需要设置伸缩比例即可 setStretchFactor
void ViewWnd::InitUi()
{
QVBoxLayout* view_layout = new QVBoxLayout(this);
view_layout->setMargin(0);
view_layout->setContentsMargins(QMargins(0, 0, 0, 0));
view_layout->addSpacing(0);
setLayout(view_layout);
//view 标题栏
m_title_wnd.reset(new ViewTitleWnd(this));
m_title_wnd->setFixedHeight(VIEWTITLE_BUTTON_HEIGHT);
view_layout->addWidget(m_title_wnd.get());
//view_layout->addStretch();
//view播放区域
m_stacked_layout.reset(new QStackedLayout(view_layout));
//QSize view_size(this->width(), this->height()- m_title_wnd->height());
if (!m_monitor_wnd) {
m_monitor_wnd.reset(new MonitorWnd(this));
m_stacked_layout->addWidget(m_monitor_wnd.get());
m_stacked_layout->setCurrentWidget(m_monitor_wnd.get());
m_title_wnd->SetBtnStatusType(TitleTabType::TitleTabType_Monitor);//初始化显示监视器
m_module_map[TitleTabType::TitleTabType_Monitor] = m_monitor_wnd;
}
if (!m_emap_wnd) {
m_emap_wnd.reset(new EMapWnd(this));
m_stacked_layout->addWidget(m_emap_wnd.get());
m_module_map[TitleTabType::TitleTabType_EMap] = m_emap_wnd;
}
if (!m_terminal_wnd) {
m_terminal_wnd.reset(new TerminalPreviewWnd(this));
m_stacked_layout->addWidget(m_terminal_wnd.get());
m_module_map[TitleTabType::TitleTabType_TerminalPreView] = m_terminal_wnd;
}
connect(m_title_wnd.get(), &ViewTitleWnd::sig_tabIndex, this, &ViewWnd::slot_TitleClicked);
}
以上 m_monitor_wnd 、m_emap_wnd、m_terminal_wnd为三个子界面的对象。
void MonitorWnd::InitUi()
{
QHBoxLayout* main_layout = new QHBoxLayout(this);
main_layout->setMargin(0);
main_layout->setContentsMargins(QMargins(0, 0, 0, 0));
main_layout->setSpacing(0);
QWidget* play_wnd = new QWidget(this);
play_wnd->setObjectName("MonitorPlayWnd");
QVBoxLayout* play_layout = new QVBoxLayout(play_wnd);
play_layout->setMargin(0);
play_layout->setContentsMargins(QMargins(0, 0, 0, 0));
play_layout->setSpacing(0);
play_wnd->setLayout(play_layout);
//play_layout->addStretch();
{
m_monitor_name.reset( new QLabel(this));
m_monitor_name->setFixedHeight(MONITOR_NAME_H);
play_layout->addWidget(m_monitor_name.get(), 0, Qt::AlignVCenter);
m_playpannel.reset(new PlayPannel(false, true, true, true, true, true, true, true, MAX_WND_VIDEO, this));
//int height = this->height();
//m_playpannel->setFixedHeight(this->height() - m_monitor_name->height() - MONITOR_CTROLAREA_H);
QWidget* ctr_area = new QWidget(play_wnd);
ctr_area->setObjectName("MonitorCtrArea");
ctr_area->setFixedHeight(MONITOR_CTROLAREA_H);
play_layout->addWidget(m_playpannel.get());
play_layout->addWidget(ctr_area);
}
//右侧设备显示区
//QWidget* list_monitors = new QWidget(this);
//QSize monitorlist_size = QSize(this->width()/5, this->height());
m_monitorlist_wnd.reset(new MonitorListWnd(this));
main_layout->addWidget(play_wnd,4);
main_layout->addWidget(m_monitorlist_wnd.get(), 1);
this->setLayout(main_layout);
}
//play_layout->addStretch();这个是空白间隔符,不要随意添加,显示异常还难以排查。
总结: 使用QHBoxLayout QVBoxLayout 然后 addWidget, 有时候会用到addSpacing(), addStrech(),但是要谨慎;添加子界面不需要设置固定大小setFixSize(.....),只需要在添加到Layout时设置伸缩比例即可:
main_layout->addWidget(play_wnd,4);
main_layout->addWidget(m_monitorlist_wnd.get(), 1);