📄 qmdiarea.cpp
字号:
bool useHorizontalScrollBar = useScrollBar(childrenRect, maxSize, Qt::Horizontal); bool useVerticalScrollBar = useScrollBar(childrenRect, maxSize, Qt::Vertical); if (useHorizontalScrollBar && !useVerticalScrollBar) { const QSize max = maxSize - QSize(0, hbarExtent.height()); useVerticalScrollBar = useScrollBar(childrenRect, max, Qt::Vertical); } if (useVerticalScrollBar && !useHorizontalScrollBar) { const QSize max = maxSize - QSize(vbarExtent.width(), 0); useHorizontalScrollBar = useScrollBar(childrenRect, max, Qt::Horizontal); } if (useHorizontalScrollBar && hbarpolicy != Qt::ScrollBarAlwaysOn) maxSize.rheight() -= hbarExtent.height(); if (useVerticalScrollBar && vbarpolicy != Qt::ScrollBarAlwaysOn) maxSize.rwidth() -= vbarExtent.width(); QRect viewportRect(QPoint(0, 0), maxSize); const int startX = q->isLeftToRight() ? childrenRect.left() : viewportRect.right() - childrenRect.right(); // Horizontal scroll bar. const int xOffset = startX + hbar->value(); hbar->setRange(qMin(0, xOffset), qMax(0, xOffset + childrenRect.width() - viewportRect.width())); hbar->setPageStep(childrenRect.width()); hbar->setSingleStep(childrenRect.width() / 20); // Vertical scroll bar. const int yOffset = childrenRect.top() + vbar->value(); vbar->setRange(qMin(0, yOffset), qMax(0, yOffset + childrenRect.height() - viewportRect.height())); vbar->setPageStep(childrenRect.height()); vbar->setSingleStep(childrenRect.height() / 20);}/*! \internal*/void QMdiAreaPrivate::internalRaise(QMdiSubWindow *mdiChild) const{ if (!sanityCheck(mdiChild, "QMdiArea::internalRaise") || childWindows.size() < 2) return; QMdiSubWindow *stackUnderChild = 0; if (!windowStaysOnTop(mdiChild)) { foreach (QObject *object, q_func()->viewport()->children()) { QMdiSubWindow *child = qobject_cast<QMdiSubWindow *>(object); if (!child || !childWindows.contains(child)) continue; if (!child->isHidden() && windowStaysOnTop(child)) { if (stackUnderChild) child->stackUnder(stackUnderChild); else child->raise(); stackUnderChild = child; } } } if (stackUnderChild) mdiChild->stackUnder(stackUnderChild); else mdiChild->raise();}/*! \internal*/bool QMdiAreaPrivate::scrollBarsEnabled() const{ return hbarpolicy != Qt::ScrollBarAlwaysOff || vbarpolicy != Qt::ScrollBarAlwaysOff;}/*! \internal*/bool QMdiAreaPrivate::lastWindowAboutToBeDestroyed() const{ if (childWindows.count() != 1) return false; QMdiSubWindow *last = childWindows.at(0); if (!last) return true; if (!last->testAttribute(Qt::WA_DeleteOnClose)) return false; return last->d_func()->data.is_closing;}/*! \internal*/void QMdiAreaPrivate::setChildActivationEnabled(bool enable, bool onlyNextActivationEvent) const{ foreach (QMdiSubWindow *subWindow, childWindows) { if (!subWindow || !subWindow->isVisible()) continue; if (onlyNextActivationEvent) subWindow->d_func()->ignoreNextActivationEvent = !enable; else subWindow->d_func()->activationEnabled = enable; }}/*! \internal \reimp*/void QMdiAreaPrivate::scrollBarPolicyChanged(Qt::Orientation orientation, Qt::ScrollBarPolicy policy){ if (childWindows.isEmpty()) return; const QMdiSubWindow::SubWindowOption option = orientation == Qt::Horizontal ? QMdiSubWindow::AllowOutsideAreaHorizontally : QMdiSubWindow::AllowOutsideAreaVertically; const bool enable = policy != Qt::ScrollBarAlwaysOff; foreach (QMdiSubWindow *child, childWindows) { if (!sanityCheck(child, "QMdiArea::scrollBarPolicyChanged")) continue; child->setOption(option, enable); } updateScrollBars();}QList<QMdiSubWindow *> QMdiAreaPrivate::subWindowList(QMdiArea::WindowOrder order, bool reversed) const{ QList<QMdiSubWindow *> list; if (childWindows.isEmpty()) return list; if (order == QMdiArea::CreationOrder) { foreach (QMdiSubWindow *child, childWindows) { if (!child) continue; if (!reversed) list.append(child); else list.prepend(child); } } else { // StackingOrder foreach (QObject *object, viewport->children()) { QMdiSubWindow *child = qobject_cast<QMdiSubWindow *>(object); if (!child || !childWindows.contains(child)) continue; if (!reversed) list.append(child); else list.prepend(child); } } return list;}/*! Constructs an empty mdi area. \a parent is passed to QWidget's constructor.*/QMdiArea::QMdiArea(QWidget *parent) : QAbstractScrollArea(*new QMdiAreaPrivate, parent){ setBackgroundRole(QPalette::Dark); setBackground(palette().brush(QPalette::Dark)); setFrameStyle(QFrame::NoFrame); setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); setViewport(0); setFocusPolicy(Qt::NoFocus); QApplication::instance()->installEventFilter(this);}/*! Destroys the MDI area.*/QMdiArea::~QMdiArea(){ Q_D(QMdiArea); delete d->cascader; d->cascader = 0; delete d->regularTiler; d->regularTiler = 0; delete d->iconTiler; d->iconTiler = 0; delete d->placer; d->placer = 0;}/*! \reimp*/QSize QMdiArea::sizeHint() const{ // Calculate a proper scale factor for QDesktopWidget::size(). // This also takes into account that we can have nested workspaces. int nestedCount = 0; QWidget *widget = this->parentWidget(); while (widget) { if (qobject_cast<QMdiArea *>(widget)) ++nestedCount; widget = widget->parentWidget(); } const int scaleFactor = 3 * (nestedCount + 1); QSize desktopSize = QApplication::desktop()->size(); QSize size(desktopSize.width() * 2 / scaleFactor, desktopSize.height() * 2 / scaleFactor); foreach (QMdiSubWindow *child, d_func()->childWindows) { if (!sanityCheck(child, "QMdiArea::sizeHint")) continue; size = size.expandedTo(child->sizeHint()); } return size.expandedTo(QApplication::globalStrut());}/*! \reimp*/QSize QMdiArea::minimumSizeHint() const{ Q_D(const QMdiArea); QSize size(style()->pixelMetric(QStyle::PM_MdiSubWindowMinimizedWidth), style()->pixelMetric(QStyle::PM_TitleBarHeight)); size = size.expandedTo(QAbstractScrollArea::minimumSizeHint()); if (!d->scrollBarsEnabled()) { foreach (QMdiSubWindow *child, d->childWindows) { if (!sanityCheck(child, "QMdiArea::sizeHint")) continue; size = size.expandedTo(child->minimumSizeHint()); } } return size.expandedTo(QApplication::globalStrut());}/*! Returns a pointer to the current subwindow, or 0 if there is no current subwindow. This function will return the same as activeSubWindow() if the QApplication containing QMdiArea is active. \sa activeSubWindow(), QApplication::activeWindow()*/QMdiSubWindow *QMdiArea::currentSubWindow() const{ Q_D(const QMdiArea); if (d->childWindows.isEmpty()) return 0; if (d->active) return d->active; if (d->isActivated && !window()->isMinimized()) return 0; Q_ASSERT(d->indicesToStackedChildren.count() > 0); int index = d->indicesToStackedChildren.at(0); Q_ASSERT(index >= 0 && index < d->childWindows.size()); QMdiSubWindow *current = d->childWindows.at(index); Q_ASSERT(current); return current;}/*! Returns a pointer to the current active subwindow. If no window is currently active, 0 is returned. Subwindows are treated as top-level windows with respect to window state, i.e., if a widget outside the MDI area is the active window, no subwindow will be active. Note that if a widget in the window in which the MDI area lives gains focus, the window will be activated. \sa setActiveSubWindow(), Qt::WindowState*/QMdiSubWindow *QMdiArea::activeSubWindow() const{ Q_D(const QMdiArea); return d->active;}/*! Activates the subwindow \a window. If \a window is 0, any current active window is deactivated. \sa activeSubWindow()*/void QMdiArea::setActiveSubWindow(QMdiSubWindow *window){ Q_D(QMdiArea); if (!window) { d->activateWindow(0); return; } if (d->childWindows.isEmpty()) { qWarning("QMdiArea::setActiveSubWindow: workspace is empty"); return; } if (d->childWindows.indexOf(window) == -1) { qWarning("QMdiArea::setActiveSubWindow: window is not inside workspace"); return; } d->activateWindow(window);}/*! Closes the active subwindow. \sa closeAllSubWindows()*/void QMdiArea::closeActiveSubWindow(){ Q_D(QMdiArea); if (d->active) d->active->close();}/*! Returns a list of all subwindows in the MDI area. If \a order is CreationOrder (the default), the windows are sorted in the order in which they were inserted into the workspace. If \a order is StackingOrder, the windows are listed in their stacking order, with the topmost window as the last item in the list. \sa WindowOrder*/QList<QMdiSubWindow *> QMdiArea::subWindowList(WindowOrder order) const{ Q_D(const QMdiArea); return d->subWindowList(order, false);}/*! Closes all subwindows by sending a QCloseEvent to each window. You may receive subWindowActivated() signals from subwindows before they are closed (if the MDI area activates the subwindow when another is closing). Subwindows that ignore the close event will remain open. \sa closeActiveSubWindow()*/void QMdiArea::closeAllSubWindows(){ Q_D(QMdiArea); if (d->childWindows.isEmpty()) return; d->isSubWindowsTiled = false; foreach (QMdiSubWindow *child, d->childWindows) { if (!sanityCheck(child, "QMdiArea::closeAllSubWindows")) continue; child->close(); } d->updateScrollBars();}/*! Gives the keyboard focus to the next window in the list of child windows. The windows are activated in the order in which they are created (CreationOrder). \sa activatePreviousSubWindow()*/void QMdiArea::activateNextSubWindow(){ Q_D(QMdiArea); if (d->childWindows.isEmpty()) return; int index = qMax(d->indexToNextWindow, 0); Q_ASSERT(index >= 0 && index < d->childWindows.size()); if (!sanityCheck(d->childWindows.at(index), "QMdiArea::activateNextSubWindow")) return; int originalIndex = index; while (d->childWindows.at(index)->isHidden()) { setIndex(&index, index + 1, 0, d->childWindows.size() - 1, true); Q_ASSERT(index >= 0 && index < d->childWindows.size()); if (index == originalIndex) break; } if (!d->childWindows.at(index)->isHidden()) d->activateWindow(d->childWindows.at(index));}/*! Gives the keyboard focus to the previous window in the list of child windows. The windows are activated in the order in which they are created (CreationOrder). \sa activateNextSubWindow()*/void QMdiArea::activatePreviousSubWindow(){ Q_D(QMdiArea); if (d->childWindows.isEmpty()) return; int index = d->indexToPreviousWindow >= 0 ? d->indexToPreviousWindow : d->childWindows.size() - 1; Q_ASSERT(index >= 0 && index < d->childWindows.size()); if (!sanityCheck(d->childWindows.at(index), "QMdiArea::activatePreviousSubWindow")) return; int originalIndex = index; while (d->childWindows.at(index)->isHidden()) { setIndex(&index, index - 1, 0, d->childWindows.size() - 1, false); Q_ASSERT(index >= 0 && index < d->childWindows.size()); if (index == originalIndex) break; } if (!d->childWindows.at(index)->isHidden()) d->activateWindow(d->childWindows.at(index));}/*! Adds \a widget as a new subwindow to the MDI area. If \a windowFlags are non-zero, they will override the flags set on the widget. The \a widget can be either a QMdiSubWindow or another QWidget (in which case the MDI area will create a subwindow and set the \a widget as the internal widget). \note Once the subwindow has been added, its parent will be the \e{viewport widget} of the QMdiArea. \quotefromfile snippets/mdiareasnippets.cpp \skipto /QMdiArea mdiArea/ \printto /subWindow1->show/ When you create your own subwindow, you must set the Qt::WA_DeleteOnClose widget attribute if you want the window to be deleted when closed in the MDI area. If not, the window will be hidden and the MDI area will not activate the next subwindow. Returns the QMdiSubWindow that is added to the MDI area. \sa removeSubWindow()*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -