⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 qtabbar.cpp

📁 奇趣公司比较新的qt/emd版本
💻 CPP
📖 第 1 页 / 共 3 页
字号:
/******************************************************************************** Copyright (C) 1992-2007 Trolltech ASA. All rights reserved.**** This file is part of the QtGui module of the Qt Toolkit.**** This file may be used under the terms of the GNU General Public** License version 2.0 as published by the Free Software Foundation** and appearing in the file LICENSE.GPL included in the packaging of** this file.  Please review the following information to ensure GNU** General Public Licensing requirements will be met:** http://trolltech.com/products/qt/licenses/licensing/opensource/**** If you are unsure which license is appropriate for your use, please** review the following information:** http://trolltech.com/products/qt/licenses/licensing/licensingoverview** or contact the sales department at sales@trolltech.com.**** In addition, as a special exception, Trolltech gives you certain** additional rights. These rights are described in the Trolltech GPL** Exception version 1.0, which can be found at** http://www.trolltech.com/products/qt/gplexception/ and in the file** GPL_EXCEPTION.txt in this package.**** In addition, as a special exception, Trolltech, as the sole copyright** holder for Qt Designer, grants users of the Qt/Eclipse Integration** plug-in the right for the Qt/Eclipse Integration to link to** functionality provided by Qt Designer and its related libraries.**** Trolltech reserves all rights not expressly granted herein.**** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.******************************************************************************/#include "private/qlayoutengine_p.h"#include "qabstractitemdelegate.h"#include "qapplication.h"#include "qbitmap.h"#include "qcursor.h"#include "qevent.h"#include "qpainter.h"#include "qstyle.h"#include "qstyleoption.h"#include "qstylepainter.h"#include "qtabwidget.h"#include "qtooltip.h"#include "qwhatsthis.h"#include "private/qtextengine_p.h"#ifndef QT_NO_ACCESSIBILITY#include "qaccessible.h"#endif#include "qdebug.h"#include "private/qtabbar_p.h"#ifndef QT_NO_TABBARinline static bool verticalTabs(QTabBar::Shape shape){    return shape == QTabBar::RoundedWest           || shape == QTabBar::RoundedEast           || shape == QTabBar::TriangularWest           || shape == QTabBar::TriangularEast;}/*!    Initialize \a option with the values from the tab at \a tabIndex. This method    is useful for subclasses when they need a QStyleOptionTab or QStyleOptionTabV2, but don't want    to fill in all the information themselves. This function will check the version    of the QStyleOptionTab and fill in the additional values for a    QStyleOptionTabV2.    \sa QStyleOption::initFrom() QTabWidget::initStyleOption()*/void QTabBar::initStyleOption(QStyleOptionTab *option, int tabIndex) const{    Q_D(const QTabBar);    int totalTabs = d->tabList.size();    if (!option || (tabIndex < 0 || tabIndex >= totalTabs))        return;    const QTabBarPrivate::Tab &tab = d->tabList.at(tabIndex);    option->initFrom(this);    option->state &= ~(QStyle::State_HasFocus | QStyle::State_MouseOver);    option->rect = tabRect(tabIndex);    bool isCurrent = tabIndex == d->currentIndex;    option->row = 0;    if (tabIndex == d->pressedIndex)        option->state |= QStyle::State_Sunken;    if (isCurrent)        option->state |= QStyle::State_Selected;    if (isCurrent && hasFocus())        option->state |= QStyle::State_HasFocus;    if (!tab.enabled)        option->state &= ~QStyle::State_Enabled;    if (isActiveWindow())        option->state |= QStyle::State_Active;    if (option->rect == d->hoverRect)        option->state |= QStyle::State_MouseOver;    option->shape = d->shape;    option->text = tab.text;    if (tab.textColor.isValid())        option->palette.setColor(foregroundRole(), tab.textColor);    option->icon = tab.icon;    if (QStyleOptionTabV2 *optionV2 = qstyleoption_cast<QStyleOptionTabV2 *>(option))        optionV2->iconSize = iconSize();  // Will get the default value then.    if (tabIndex > 0 && tabIndex - 1 == d->currentIndex)        option->selectedPosition = QStyleOptionTab::PreviousIsSelected;    else if (tabIndex < totalTabs - 1 && tabIndex + 1 == d->currentIndex)        option->selectedPosition = QStyleOptionTab::NextIsSelected;    else        option->selectedPosition = QStyleOptionTab::NotAdjacent;    if (tabIndex == 0) {        if (totalTabs > 1)            option->position = QStyleOptionTab::Beginning;        else            option->position = QStyleOptionTab::OnlyOneTab;    } else if (tabIndex == totalTabs - 1) {        option->position = QStyleOptionTab::End;    } else {        option->position = QStyleOptionTab::Middle;    }#ifndef QT_NO_TABWIDGET    if (const QTabWidget *tw = qobject_cast<const QTabWidget *>(parentWidget())) {        if (tw->cornerWidget(Qt::TopLeftCorner) || tw->cornerWidget(Qt::BottomLeftCorner))            option->cornerWidgets |= QStyleOptionTab::LeftCornerWidget;        if (tw->cornerWidget(Qt::TopRightCorner) || tw->cornerWidget(Qt::BottomRightCorner))            option->cornerWidgets |= QStyleOptionTab::RightCornerWidget;    }    int hframe  = style()->pixelMetric(QStyle::PM_TabBarTabHSpace, option, this);    option->text = fontMetrics().elidedText(option->text, d->elideMode,                        1 + (verticalTabs(d->shape) ? tab.rect.height() : tab.rect.width()) - hframe,                        Qt::TextShowMnemonic);#endif}/*!    \class QTabBar    \brief The QTabBar class provides a tab bar, e.g. for use in tabbed dialogs.    \ingroup advanced    \mainclass    QTabBar is straightforward to use; it draws the tabs using one of    the predefined \link QTabBar::Shape shapes\endlink, and emits a    signal when a tab is selected. It can be subclassed to tailor the    look and feel. Qt also provides a ready-made \l{QTabWidget}.    Each tab has a tabText(), an optional tabIcon(), an optional    tabToolTip(), optional tabWhatsThis() and optional tabData().    The tabs's attributes can be changed with setTabText(), setTabIcon(),    setTabToolTip(), setTabWhatsThis and setTabData(). Each tabs can be    enabled or disabled individually with setTabEnabled().    Each tab can display text in a distinct color. The current text color    for a tab can be found with the tabTextColor() function. Set the text    color for a particular tab with setTabTextColor().    Tabs are added using addTab(), or inserted at particular positions    using insertTab(). The total number of tabs is given by    count(). Tabs can be removed from the tab bar with    removeTab(). Combining removeTab() and insertTab() allows you to    move tabs to different positions.    The \l shape property defines the tabs' appearance. The choice of    shape is a matter of taste, although tab dialogs (for preferences    and similar) invariably use \l RoundedNorth.    Tab controls in windows other than dialogs almost    always use either \l RoundedSouth or \l TriangularSouth. Many    spreadsheets and other tab controls in which all the pages are    essentially similar use \l TriangularSouth, whereas \l    RoundedSouth is used mostly when the pages are different (e.g. a    multi-page tool palette). The default in QTabBar is \l    RoundedNorth.    The most important part of QTabBar's API is the currentChanged()    signal.  This is emitted whenever the current tab changes (even at    startup, when the current tab changes from 'none'). There is also    a slot, setCurrentIndex(), which can be used to select a tab    programmatically. The function currentIndex() returns the index of    the current tab, \l count holds the number of tabs.    QTabBar creates automatic mnemonic keys in the manner of QAbstractButton;    e.g. if a tab's label is "\&Graphics", Alt+G becomes a shortcut    key for switching to that tab.    The following virtual functions may need to be reimplemented in    order to tailor the look and feel or store extra data with each    tab:    \list    \i tabSizeHint() calcuates the size of a tab.    \i tabInserted() notifies that a new tab was added.    \i tabRemoved() notifies that a tab was removed.    \i tabLayoutChange() notifies that the tabs have been re-laid out.    \i paintEvent() paints all tabs.    \endlist    For subclasses, you might also need the tabRect() functions which    returns the visual geometry of a single tab.    \table 100%    \row \o \inlineimage plastique-tabbar.png Screenshot of a Plastique style tab bar         \o A tab bar shown in the Plastique widget style.    \row \o \inlineimage plastique-tabbar-truncated.png Screenshot of a truncated Plastique tab bar         \o A truncated tab bar shown in the Plastique widget style.    \endtable    \sa QTabWidget*//*!    \enum QTabBar::Shape    This enum type lists the built-in shapes supported by QTabBar. Treat these    as hints as some styles may not render some of the shapes. However,    position should be honored.    \value RoundedNorth  The normal rounded look above the pages    \value RoundedSouth  The normal rounded look below the pages    \value RoundedWest  The normal rounded look on the left side of the pages    \value RoundedEast  The normal rounded look on the right side the pages    \value TriangularNorth  Triangular tabs above the pages.    \value TriangularSouth  Triangular tabs similar to those used in    the Excel spreadsheet, for example    \value TriangularWest  Triangular tabs on the left of the pages.    \value TriangularEast  Triangular tabs on the right of the pages.    \omitvalue RoundedAbove    \omitvalue RoundedBelow    \omitvalue TriangularAbove    \omitvalue TriangularBelow*//*!    \fn void QTabBar::currentChanged(int index)    This signal is emitted when the tab bar's current tab changes. The    new current has the given \a index.*/int QTabBarPrivate::extraWidth() const{    Q_Q(const QTabBar);    return 2 * qMax(q->style()->pixelMetric(QStyle::PM_TabBarScrollButtonWidth, 0, q),                    QApplication::globalStrut().width());}void QTabBarPrivate::init(){    Q_Q(QTabBar);    leftB = new QToolButton(q);    leftB->setAutoRepeat(true);    QObject::connect(leftB, SIGNAL(clicked()), q, SLOT(_q_scrollTabs()));    leftB->hide();    rightB = new QToolButton(q);    rightB->setAutoRepeat(true);    QObject::connect(rightB, SIGNAL(clicked()), q, SLOT(_q_scrollTabs()));    rightB->hide();#ifdef QT_KEYPAD_NAVIGATION    if (QApplication::keypadNavigationEnabled()) {        leftB->setFocusPolicy(Qt::NoFocus);        rightB->setFocusPolicy(Qt::NoFocus);        q->setFocusPolicy(Qt::NoFocus);    } else#endif    q->setFocusPolicy(Qt::TabFocus);    q->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);    elideMode = Qt::TextElideMode(q->style()->styleHint(QStyle::SH_TabBar_ElideMode, 0, q));    useScrollButtons = !q->style()->styleHint(QStyle::SH_TabBar_PreferNoArrows, 0, q);}QTabBarPrivate::Tab *QTabBarPrivate::at(int index){    return validIndex(index)?&tabList[index]:0;}const QTabBarPrivate::Tab *QTabBarPrivate::at(int index) const{    return validIndex(index)?&tabList[index]:0;}int QTabBarPrivate::indexAtPos(const QPoint &p) const{    Q_Q(const QTabBar);    if (q->tabRect(currentIndex).contains(p))        return currentIndex;    for (int i = 0; i < tabList.count(); ++i)        if (tabList.at(i).enabled && q->tabRect(i).contains(p))            return i;    return -1;}void QTabBarPrivate::layoutTabs(){    Q_Q(QTabBar);    scrollOffset = 0;    layoutDirty = false;    QSize size = q->size();    int last, available;    int maxExtent;    int i;    bool vertTabs = verticalTabs(shape);    int tabChainIndex = 0;    Qt::Alignment tabAlignment = Qt::Alignment(q->style()->styleHint(QStyle::SH_TabBar_Alignment, 0, q));    QVector<QLayoutStruct> tabChain(tabList.count() + 2);    // We put an empty item at the front and back and set its expansive attribute    // depending on tabAlignment.    tabChain[tabChainIndex].init();    tabChain[tabChainIndex].expansive = tabAlignment != Qt::AlignLeft;    tabChain[tabChainIndex].empty = true;    ++tabChainIndex;    // We now go through our list of tabs and set the minimum size and the size hint    // This will allow us to elide text if necessary. Since we don't set    // a maximum size, tabs will EXPAND to fill up the empty space.    // Since tab widget is rather *ahem* strict about keeping the geometry of the    // tab bar to its absolute minimum, this won't bleed through, but will show up    // if you use tab bar on its own (a.k.a. not a bug, but a feature).    // Update: if squeezeTabs is true, we DO set a maximum size to prevent the tabs    // being wider than necessary.    if (!vertTabs) {        int minx = 0;        int x = 0;        int maxHeight = 0;        for (i = 0; i < tabList.count(); ++i, ++tabChainIndex) {            QSize sz = q->tabSizeHint(i);            tabList[i].maxRect = QRect(x, 0, sz.width(), sz.height());            x += sz.width();            maxHeight = qMax(maxHeight, sz.height());            sz = minimumTabSizeHint(i);            tabList[i].minRect = QRect(minx, 0, sz.width(), sz.height());            minx += sz.width();            tabChain[tabChainIndex].init();            tabChain[tabChainIndex].sizeHint = tabList.at(i).maxRect.width();            tabChain[tabChainIndex].minimumSize = sz.width();            tabChain[tabChainIndex].empty = false;            tabChain[tabChainIndex].expansive = true;            if (squeezeTabs)                tabChain[tabChainIndex].maximumSize = tabChain[tabChainIndex].sizeHint;        }        last = minx;        available = size.width();        maxExtent = maxHeight;    } else {        int miny = 0;        int y = 0;        int maxWidth = 0;        for (i = 0; i < tabList.count(); ++i, ++tabChainIndex) {            QSize sz = q->tabSizeHint(i);            tabList[i].maxRect = QRect(0, y, sz.width(), sz.height());            y += sz.height();            maxWidth = qMax(0, sz.width());            sz = minimumTabSizeHint(i);            tabList[i].minRect = QRect(0, miny, sz.width(), sz.height());            miny += sz.height();            tabChain[tabChainIndex].init();            tabChain[tabChainIndex].sizeHint = tabList.at(i).maxRect.height();            tabChain[tabChainIndex].minimumSize = sz.height();            tabChain[tabChainIndex].empty = false;            tabChain[tabChainIndex].expansive = true;            if (squeezeTabs)                tabChain[tabChainIndex].maximumSize = tabChain[tabChainIndex].sizeHint;        }        last = miny;        available = size.height();        maxExtent = maxWidth;    }    Q_ASSERT(tabChainIndex == tabChain.count() - 1); // add an assert just to make sure.    // Mirror our front item.    tabChain[tabChainIndex].init();    tabChain[tabChainIndex].expansive = tabAlignment != Qt::AlignRight;    tabChain[tabChainIndex].empty = true;    // Do the calculation    qGeomCalc(tabChain, 0, tabChain.count(), 0, qMax(available, last), 0);    // Use the results    for (i = 0; i < tabList.count(); ++i) {        const QLayoutStruct &lstruct = tabChain.at(i + 1);        if (!vertTabs)            tabList[i].rect.setRect(lstruct.pos, 0, lstruct.size, maxExtent);        else            tabList[i].rect.setRect(0, lstruct.pos, maxExtent, lstruct.size);    }    if (useScrollButtons && tabList.count() && last > available) {        int extra = extraWidth();        if (!vertTabs) {            Qt::LayoutDirection ld = q->layoutDirection();            QRect arrows = QStyle::visualRect(ld, q->rect(),                                              QRect(available - extra, 0, extra, size.height()));            if (ld == Qt::LeftToRight) {                leftB->setGeometry(arrows.left(), arrows.top(), extra/2, arrows.height());                rightB->setGeometry(arrows.right() - extra/2 + 1, arrows.top(),                                    extra/2, arrows.height());                leftB->setArrowType(Qt::LeftArrow);                rightB->setArrowType(Qt::RightArrow);            } else {                rightB->setGeometry(arrows.left(), arrows.top(), extra/2, arrows.height());                leftB->setGeometry(arrows.right() - extra/2 + 1, arrows.top(),                                    extra/2, arrows.height());                rightB->setArrowType(Qt::LeftArrow);                leftB->setArrowType(Qt::RightArrow);            }        } else {            QRect arrows = QRect(0, available - extra, size.width(), extra );            leftB->setGeometry(arrows.left(), arrows.top(), arrows.width(), extra/2);            leftB->setArrowType(Qt::UpArrow);            rightB->setGeometry(arrows.left(), arrows.bottom() - extra/2 + 1,                                arrows.width(), extra/2);            rightB->setArrowType(Qt::DownArrow);        }        leftB->setEnabled(scrollOffset > 0);        rightB->setEnabled(last - scrollOffset >= available - extra);        leftB->show();        rightB->show();    } else {        rightB->hide();        leftB->hide();    }    q->tabLayoutChange();}void QTabBarPrivate::makeVisible(int index){    Q_Q(QTabBar);    if (!validIndex(index) || leftB->isHidden())        return;    const QRect tabRect = tabList.at(index).rect;    const int oldScrollOffset = scrollOffset;    const bool horiz = !verticalTabs(shape);    const int available = (horiz ? q->width() : q->height()) - extraWidth();    const int start = horiz ? tabRect.left() : tabRect.top();    const int end = horiz ? tabRect.right() : tabRect.bottom();    if (start < scrollOffset) // too far left        scrollOffset = start - (index?8:0);    else if (end > scrollOffset + available) // too far right        scrollOffset = end - available + 1;    leftB->setEnabled(scrollOffset > 0);    const int last = horiz ? tabList.last().rect.right() : tabList.last().rect.bottom();    rightB->setEnabled(last - scrollOffset >= available);    if (oldScrollOffset != scrollOffset)        q->update();}void QTabBarPrivate::_q_scrollTabs(){    Q_Q(QTabBar);    const QObject *sender = q->sender();    int i = -1;    if (!verticalTabs(shape)) {        if (sender == leftB) {            for (i = tabList.count() - 1; i >= 0; --i) {                if (tabList.at(i).rect.left() - scrollOffset < 0) {                    makeVisible(i);                    return;                }            }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -