qt渐变大小窗口

qq:609162385
这里写图片描述


#include "alt_key.hpp"
#include "finddialog.hpp"
#include <QCheckBox>
#include <QComboBox>
#include <QDialogButtonBox>
#include <QFormLayout>
#include <QGraphicsOpacityEffect>
#include <QLabel>
#include <QLineEdit>
#include <QPropertyAnimation>
#include <QPushButton>
#include <QSignalTransition>
#include <QState>
#include <QStateMachine>
#include <QTimer>


#ifdef Q_WS_MAC
const int Duration = 1000;
#else
const int Duration = 1500;
#endif


QVariant fontInterpolator(const QFont &start, const QFont &end,
                          qreal progress)
{
    qreal startSize = start.pointSizeF();
    qreal endSize = end.pointSizeF();
    qreal newSize = startSize + ((endSize - startSize) *
                                qBound(0.0, progress, 1.0));
    QFont font(start);
    font.setPointSizeF(newSize);
    return font;
}


FindDialog::FindDialog(QWidget *parent)
    : QDialog(parent), margin(0)
{
    qRegisterAnimationInterpolator<QFont>(fontInterpolator);
    createWidgets();
    createLayout();
    createConnections();

    findTextLineEdit->setFocus();
    AQP::accelerateWidget(this);
    QTimer::singleShot(0, this, SLOT(createStateMachines()));
}


void FindDialog::createWidgets()
{
    findTextLineEdit = new QLineEdit;
    caseSensitiveCheckBox = new QCheckBox(tr("Case Sensitive"));
    caseSensitiveCheckBox->setChecked(true);

    wholeWordsCheckBox = new QCheckBox(tr("Whole Words Only"), this);
    wholeWordsCheckBox->setChecked(false);

    syntaxLabel = new QLabel(tr("Syntax:"), this);

    syntaxComboBox = new QComboBox(this);
    syntaxLabel->setBuddy(syntaxComboBox);
    syntaxComboBox->addItem(tr("Literal"), QRegExp::FixedString);
    syntaxComboBox->addItem(tr("Regex"), QRegExp::RegExp2);
    syntaxComboBox->addItem(tr("Wildcard"), QRegExp::Wildcard);
    syntaxComboBox->setCurrentIndex(0);

    extraWidgets << wholeWordsCheckBox << syntaxLabel
                 << syntaxComboBox;

    foreach (QWidget *widget, extraWidgets) {
        QGraphicsOpacityEffect *effect = new QGraphicsOpacityEffect;
        effect->setOpacity(1.0);
        widget->setGraphicsEffect(effect);
    }

    buttonBox = new QDialogButtonBox(QDialogButtonBox::Close,
                                     Qt::Vertical);
    findButton = buttonBox->addButton(tr("Find"),
            QDialogButtonBox::AcceptRole);
    moreButton = buttonBox->addButton(tr("More"),
            QDialogButtonBox::ActionRole);
    moreButton->setCheckable(true);
}


void FindDialog::createLayout()
{
    QFormLayout *topLeftLayout = new QFormLayout;
    topLeftLayout->addRow(tr("Find:"), findTextLineEdit);
    topLeftLayout->addRow(caseSensitiveCheckBox);
    QHBoxLayout *layout = new QHBoxLayout;
    layout->addLayout(topLeftLayout);
    layout->addWidget(buttonBox);
    setLayout(layout);

    int left, top, right, bottom;
    layout->getContentsMargins(&left, &top, &right, &bottom);
    margin = qMax(qMax(left, right), qMax(top, bottom));
}


void FindDialog::createStateMachines()
{
    findStateMachine = new QStateMachine(this);
    createFindStates();
    createFindTransitions();
    findStateMachine->setInitialState(nothingToFindState);
    findStateMachine->start();

    extraStateMachine = new QStateMachine(this);
    createShowExtraWidgetsState();
    createHideExtraWidgetsState();
    createShowExtraWidgetsTransitions();
    createHideExtraWidgetsTransitions();
    extraStateMachine->setInitialState(hideExtraWidgetsState);
    extraStateMachine->start();
}


void FindDialog::createFindStates()
{
    nothingToFindState = new QState(findStateMachine);
    nothingToFindState->assignProperty(findButton, "enabled", false);

    somethingToFindState = new QState(findStateMachine);
    somethingToFindState->assignProperty(findButton, "enabled", true);
}


void FindDialog::createFindTransitions()
{
    nothingToFindState->addTransition(this,
            SIGNAL(findTextIsNonEmpty()), somethingToFindState);
    somethingToFindState->addTransition(this,
            SIGNAL(findTextIsEmpty()), nothingToFindState);
}


void FindDialog::createShowExtraWidgetsState()
{
    QSize size = extraSize();
    size.rheight() += minimumSizeHint().height();
    size.setWidth(qMax(size.width(), minimumSizeHint().width()));

    QList<QRectF> rects;
    int y = sizeHint().height() - margin;
    rects << QRectF(margin, y, wholeWordsCheckBox->sizeHint().width(),
                    wholeWordsCheckBox->sizeHint().height());
    y += wholeWordsCheckBox->sizeHint().height() + margin;
    int height = qMax(syntaxLabel->sizeHint().height(),
                      syntaxComboBox->sizeHint().height());
    int width = syntaxLabel->sizeHint().width();
    rects << QRectF(margin, y, width, height);
    int x = margin + syntaxLabel->sizeHint().width() + margin;
    width = qMin(sizeHint().width(), size.width()) - (x + margin);
    rects << QRectF(x, y, width, height);

    showExtraWidgetsState = new QState(extraStateMachine);
    foreach (QWidget *widget, extraWidgets) {
        showExtraWidgetsState->assignProperty(
                widget, "geometry", rects.takeFirst());
        showExtraWidgetsState->assignProperty(
                widget, "font", font());
        showExtraWidgetsState->assignProperty(
                widget->graphicsEffect(), "opacity", 1.0);
    }
    showExtraWidgetsState->assignProperty(this, "minimumSize", size);
}


QSize FindDialog::extraSize() const
{
    const int Width = syntaxLabel->sizeHint().width() +
            syntaxComboBox->sizeHint().width() + (2 * margin);
    const int Height = wholeWordsCheckBox->sizeHint().height() +
            qMax(syntaxLabel->sizeHint().height(),
                 syntaxComboBox->sizeHint().height()) + (2 * margin);
    return QSize(Width, Height);
}


void FindDialog::createHideExtraWidgetsState()
{
    QRectF rect = QRectF(buttonBox->x() + (moreButton->width() / 2),
            buttonBox->height() - (moreButton->height() / 2), 1, 1);
    QFont smallFont(font());
    smallFont.setPointSizeF(1.0);

    hideExtraWidgetsState = new QState(extraStateMachine);
    foreach (QWidget *widget, extraWidgets) {
        hideExtraWidgetsState->assignProperty(
                widget, "geometry", rect);
        hideExtraWidgetsState->assignProperty(
                widget, "font", smallFont);
        hideExtraWidgetsState->assignProperty(
                widget->graphicsEffect(), "opacity", 0.0);
    }
    hideExtraWidgetsState->assignProperty(
            this, "minimumSize", minimumSizeHint());
}


void FindDialog::createShowExtraWidgetsTransitions()
{
    QSignalTransition *transition =
            hideExtraWidgetsState->addTransition(this,
                    SIGNAL(showExtra()), showExtraWidgetsState);

    createCommonTransitions(transition);

    QPropertyAnimation *animation;
    animation = new QPropertyAnimation(this, "minimumSize");
    animation->setDuration(Duration / 3);
    transition->addAnimation(animation);

    animation = new QPropertyAnimation(this, "size");
    animation->setDuration(Duration / 3);
    QSize size = extraSize();
    size = QSize(qMax(size.width(), width()),
                 sizeHint().height() + size.height());
    animation->setEndValue(size);
    transition->addAnimation(animation);
}


void FindDialog::createCommonTransitions(
        QSignalTransition *transition)
{
    QPropertyAnimation *animation;
    foreach (QWidget *widget, extraWidgets) {
        animation = new QPropertyAnimation(widget, "geometry");
        animation->setDuration(Duration);
        transition->addAnimation(animation);
        animation = new QPropertyAnimation(widget, "font");
        animation->setDuration(Duration);
        transition->addAnimation(animation);
        if (QGraphicsOpacityEffect *effect =
                static_cast<QGraphicsOpacityEffect*>(
                        widget->graphicsEffect())) {
            animation = new QPropertyAnimation(effect, "opacity");
            animation->setDuration(Duration);
            animation->setEasingCurve(QEasingCurve::OutInCirc);
            transition->addAnimation(animation);
        }
    }
}


void FindDialog::createHideExtraWidgetsTransitions()
{
    QSignalTransition *transition =
            showExtraWidgetsState->addTransition(this,
                    SIGNAL(hideExtra()), hideExtraWidgetsState);

    createCommonTransitions(transition);

    QPropertyAnimation *animation = new QPropertyAnimation(this,
                                                           "size");
    animation->setDuration(Duration);
    animation->setEndValue(sizeHint());
    transition->addAnimation(animation);
}


void FindDialog::createConnections()
{
    connect(findTextLineEdit, SIGNAL(textEdited(const QString&)),
            this, SLOT(findTextChanged(const QString&)));
    connect(moreButton, SIGNAL(toggled(bool)),
            this, SLOT(showOrHideExtra(bool)));
    connect(buttonBox, SIGNAL(rejected()), this, SLOT(close()));
}


void FindDialog::findTextChanged(const QString &text)
{
    if (text.isEmpty())
        emit findTextIsEmpty();
    else
        emit findTextIsNonEmpty();
}


void FindDialog::showOrHideExtra(bool on)
{
    if (on)
        emit showExtra();
    else
        emit hideExtra();
#ifdef SCREENSHOTS
    takeScreenshot();
#endif
}


#ifdef SCREENSHOTS
void FindDialog::takeScreenshot()
{
    screenshots << QPixmap::grabWidget(this);
    if (screenshots.count() < 33)
        QTimer::singleShot(50, this, SLOT(takeScreenshot()));
}


void FindDialog::reject()
{
    for (int i = 0; i < screenshots.count(); ++i)
        screenshots.at(i).save(QString("finddialog%1.png")
                               .arg(i + 1, 2, 10, QChar('0')));
    QDialog::reject();
}
#endif

猜你喜欢

转载自blog.csdn.net/cqltbe131421/article/details/81324508
今日推荐