📄 qmainwindowlayout.cpp
字号:
// create new dock window layout static const Qt::Orientation orientations[] = { Qt::Vertical, // LEFT Qt::Vertical, // RIGHT Qt::Horizontal, // TOP Qt::Horizontal, // BOTTOM }; l = new QDockWidgetLayout(area, orientations[pos]); l->setParent(this); l->setObjectName(objectName() + "_dockwidgetLayout" + QString::number(area, 16)); info.item = l; // create separator Q_ASSERT(!info.sep); info.sep = new QWidgetItem(new QDockSeparator(l, parentWidget())); } else { l = qobject_cast<QDockWidgetLayout *>(info.item->layout()); Q_ASSERT(l != 0); } return l;}void QMainWindowLayout::addDockWidget(Qt::DockWidgetArea area, QDockWidget *dockwidget, Qt::Orientation orientation){ removeRecursive(dockwidget); QDockWidgetLayout * const layout = layoutForArea(area); layout->extend(dockwidget, orientation);}void QMainWindowLayout::splitDockWidget(QDockWidget *after, QDockWidget *dockwidget, Qt::Orientation orientation){ removeRecursive(dockwidget); const Qt::DockWidgetArea area = dockWidgetArea(after); QDockWidgetLayout * const layout = layoutForArea(area); QDockWidgetLayout::split(layout, after, dockwidget, (orientation == Qt::Horizontal ? Qt::RightDockWidgetArea : Qt::BottomDockWidgetArea));}#endif // QT_NO_DOCKWIDGETstatic bool findWidgetRecursively(QLayoutItem *li, QWidget *w){ QLayout *lay = li->layout(); if (!lay) return false; int i = 0; QLayoutItem *child; while ((child = lay->itemAt(i))) { if (child->widget() == w) { return true; } else if (findWidgetRecursively(child, w)) { return true; } else { ++i; } } return false;}#ifndef QT_NO_DOCKWIDGETQt::DockWidgetArea QMainWindowLayout::dockWidgetArea(QDockWidget *dockwidget) const{ for (int pos = 0; pos < NPOSITIONS - 1; ++pos) { if (!layout_info[pos].item) continue; if (findWidgetRecursively(layout_info[pos].item, dockwidget)) return static_cast<Qt::DockWidgetArea>(areaForPosition(pos)); } return Qt::DockWidgetArea(0);}#endif // QT_NO_DOCKWIDGETvoid QMainWindowLayout::saveState(QDataStream &stream) const{#ifndef QT_NO_TOOLBAR // save toolbar state stream << (uchar) ToolBarStateMarkerEx; stream << tb_layout_info.size(); // number of toolbar lines if (!tb_layout_info.isEmpty()) { for (int line = 0; line < tb_layout_info.size(); ++line) { const ToolBarLineInfo &lineInfo = tb_layout_info.at(line); stream << lineInfo.pos; stream << lineInfo.list.size(); for (int i = 0; i < lineInfo.list.size(); ++i) { const ToolBarLayoutInfo &info = lineInfo.list.at(i); QWidget *widget = info.item->widget(); QString objectName = widget->objectName(); if (objectName.isEmpty()) { qWarning("QMainWindow::saveState(): 'objectName' not set for QToolBar %p '%s'", widget, widget->windowTitle().toLocal8Bit().constData()); } stream << objectName; stream << (uchar) !widget->isHidden(); stream << info.pos; stream << info.size; stream << info.offset; stream << info.user_pos; } } }#endif // QT_NO_TOOLBAR#ifndef QT_NO_DOCKWIDGET // save dockwidget state stream << (uchar) DockWidgetStateMarker; int x = 0; for (int i = 0; i < NPOSITIONS - 1; ++i) { if (!layout_info[i].item) continue; ++x; } stream << x; for (int i = 0; i < NPOSITIONS - 1; ++i) { if (!layout_info[i].item) { continue; } stream << i; stream << layout_info[i].size; const QDockWidgetLayout * const layout = qobject_cast<const QDockWidgetLayout *>(layout_info[i].item->layout()); Q_ASSERT(layout != 0); layout->saveState(stream); }#endif // QT_NO_DOCKWIDGET // save center widget state stream << layout_info[CENTER].size;}bool QMainWindowLayout::restoreState(QDataStream &stream){#ifndef QT_NO_TOOLBAR // restore toolbar layout uchar tmarker; stream >> tmarker; if (tmarker != ToolBarStateMarker && tmarker != ToolBarStateMarkerEx) return false; int lines; stream >> lines; QList<ToolBarLineInfo> toolBarState; QList<QToolBar *> toolbars = qFindChildren<QToolBar *>(parentWidget()); for (int line = 0; line < lines; ++line) { ToolBarLineInfo lineInfo; stream >> lineInfo.pos; int size; stream >> size; for (int i = 0; i < size; ++i) { ToolBarLayoutInfo info; QString objectName; stream >> objectName; uchar shown; stream >> shown; stream >> info.pos; stream >> info.size; stream >> info.offset; if (tmarker == ToolBarStateMarkerEx) stream >> info.user_pos; if (objectName.isEmpty()) { qWarning("QMainWindow::restoreState: Cannot restore a QToolBar with an empty 'objectName'"); continue; } // find toolbar QToolBar *toolbar = 0; for (int t = 0; t < toolbars.size(); ++t) { QToolBar *tb = toolbars.at(t); if (tb && tb->objectName() == objectName) { toolbar = tb; toolbars[t] = 0; break; } } if (!toolbar) { qWarning("QMainWindow::restoreState(): cannot find a QToolBar with " "matching 'objectName' (looking for '%s').", objectName.toLocal8Bit().constData()); continue; } info.item = new QWidgetItem(toolbar); toolbar->setVisible(shown); toolbar->setOrientation((lineInfo.pos == LEFT || lineInfo.pos == RIGHT) ? Qt::Vertical : Qt::Horizontal); lineInfo.list << info; } toolBarState << lineInfo; } if (stream.status() != QDataStream::Ok) return false; // remove restored toolbars from the existing toolbar layout for (int line = 0; line < toolBarState.size(); ++line) { const ToolBarLineInfo &lineInfo = toolBarState.at(line); for (int i = 0; i < lineInfo.list.size(); ++i) { const ToolBarLayoutInfo &info = lineInfo.list.at(i); bool found = false; for (int eline = 0; !found && eline < tb_layout_info.size(); ++eline) { ToolBarLineInfo &elineInfo = tb_layout_info[eline]; for (int e = 0; !found && e < elineInfo.list.size(); ++e) { ToolBarLayoutInfo &einfo = elineInfo.list[e]; if (info.item->widget() == einfo.item->widget()) { // found it found = true; delete einfo.item; elineInfo.list.removeAt(e); if (elineInfo.list.isEmpty()) tb_layout_info.removeAt(eline); } } } } } if (!tb_layout_info.isEmpty()) { // merge toolbars that have not been restored into the restored layout int lineCount[NPOSITIONS - 1] = { 0, 0, 0, 0 }; while (!tb_layout_info.isEmpty()) { ToolBarLineInfo lineInfo = tb_layout_info.takeFirst(); ++lineCount[lineInfo.pos]; bool merged = false; int targetLine = 0; for (int line = 0; line < toolBarState.size(); ++line) { ToolBarLineInfo &restoredLineInfo = toolBarState[line]; if (lineInfo.pos != restoredLineInfo.pos) continue; if (++targetLine == lineCount[lineInfo.pos]) { // merge! restoredLineInfo.list << lineInfo.list; merged = true; } } if (!merged) { // couldn't merge this toolbar line, append it to the new layout toolBarState << lineInfo; } } } // replace existing toolbar layout tb_layout_info = toolBarState;#endif // QT_NO_TOOLBAR#ifndef QT_NO_DOCKWIDGET // restore dockwidget layout uchar dmarker; stream >> dmarker; if (dmarker != DockWidgetStateMarker) return false; QList<QDockWidget *> dockwidgets = qFindChildren<QDockWidget *>(parentWidget()); save_layout_info = new QVector<QMainWindowLayoutInfo>(layout_info); // clear out our working copy for (int i = 0; i < NPOSITIONS - 1; ++i) { layout_info[i].item = 0; layout_info[i].sep = 0; layout_info[i].size = QSize(); layout_info[i].is_dummy = false; } int areas; stream >> areas; for (int area = 0; area < areas; ++area) { int pos; stream >> pos; stream >> layout_info[pos].size; QDockWidgetLayout * const layout = layoutForArea(static_cast<Qt::DockWidgetArea>(areaForPosition(pos))); if (!layout->restoreState(stream)) { stream.setStatus(QDataStream::ReadCorruptData); break; } }#endif // QT_NO_DOCKWIDGET // restore center widget size stream >> layout_info[CENTER].size; if (stream.status() != QDataStream::Ok) { // restore failed, get rid of the evidence for (int i = 0; i < NPOSITIONS - 1; ++i) { if (layout_info[i].sep) delete layout_info[i].sep->widget(); delete layout_info[i].sep; delete layout_info[i].item; } layout_info = *save_layout_info; delete save_layout_info; save_layout_info = 0; relayout_type = QInternal::RelayoutNormal; return false; }#ifndef QT_NO_DOCKWIDGET // if any of the dockwidgets have not been restored, append them // to the end of their current area for (int i = 0; i < dockwidgets.size(); ++i) { QDockWidget *dockWidget = dockwidgets.at(i); bool found = false; for (int x = 0; !found && x < NPOSITIONS - 1; ++x) { if (layout_info[x].item) found = findWidgetRecursively(layout_info[x].item, dockWidget); } if (!found) { // append to the dock widget's current area found = false; int x = 0; for (; !found && x < NPOSITIONS - 1; ++x) { if ((*save_layout_info)[x].item) found = findWidgetRecursively((*save_layout_info)[x].item, dockWidget); } if (!found) { // the dock widget hasn't been added to this layout continue; } --x; Qt::Orientation orientation = Qt::Horizontal; switch (areaForPosition(x)) { case Qt::LeftDockWidgetArea: case Qt::RightDockWidgetArea: orientation = Qt::Vertical; break; default: break; } addDockWidget(static_cast<Qt::DockWidgetArea>(areaForPosition(x)), dockWidget, orientation); } } // replace existing dockwidget layout for (int i = 0; i < NPOSITIONS - 1; ++i) { if ((*save_layout_info)[i].sep) delete (*save_layout_info)[i].sep->widget(); delete (*save_layout_info)[i].sep; delete (*save_layout_info)[i].item; }#endif // QT_NO_DOCKWIDGET delete save_layout_info; save_layout_info = 0; relayout_type = QInternal::RelayoutNormal; return true;}int QMainWindowLayout::count() const{ qWarning("QMainWindowLayout::count()"); return 10; //#################################################}QLayoutItem *QMainWindowLayout::itemAt(int index) const{ int x = 0;#ifndef QT_NO_TOOLBAR for (int line = 0; line < tb_layout_info.size(); ++line) { const ToolBarLineInfo &lineInfo = tb_layout_info.at(line); for (int i = 0; i < lineInfo.list.size(); ++i) { if (x++ == index) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -