diff --git a/astackwidget/astackwidget.cpp b/astackwidget/astackwidget.cpp new file mode 100644 index 0000000..2f2ff16 --- /dev/null +++ b/astackwidget/astackwidget.cpp @@ -0,0 +1,172 @@ +#include "astackwidget.h" + +#include +#include + +AStackWidget::AStackWidget(QWidget *parent) + : QWidget(parent) +{ + m_offset = 0; + m_curIndex = 0; + m_lastIndex = 0; + m_duration = 500; + m_moveAnimation = new QPropertyAnimation(this, ""); + m_moveAnimation->setDuration(m_duration); + connect(m_moveAnimation, &QPropertyAnimation::valueChanged, this, &AStackWidget::onValueChanged); + connect(m_moveAnimation, &QPropertyAnimation::finished, this, &AStackWidget::onMoveFinished); +} + +AStackWidget::~AStackWidget() +{ + +} + +int AStackWidget::count() const +{ + return m_widgetLst.size(); +} + +int AStackWidget::currentIndex() const +{ + return m_curIndex; +} + +void AStackWidget::setDuration(int duration) +{ + m_duration = duration; +} + +int AStackWidget::addWidget(QWidget * widget) +{ + int index = indexOf(widget); + if (index >= 0){ + return index; + } + widget->setParent(this); + m_widgetLst.append(widget); + return count() - 1; +} + +int AStackWidget::indexOf(QWidget * widget) const +{ + return m_widgetLst.indexOf(widget); +} + +int AStackWidget::insertWidget(int index, QWidget * widget) +{ + int curindex = indexOf(widget); + if (curindex >= 0) { + return curindex; + } + widget->setParent(this); + m_widgetLst.insert(index, widget); + return index; +} + +QWidget * AStackWidget::currentWidget() const +{ + if (m_curIndex >= 0 && m_curIndex < count()){ + return m_widgetLst.at(m_curIndex); + } + return nullptr; +} + +QWidget * AStackWidget::widget(int index) const +{ + if (index >= 0 && index < count()) { + return m_widgetLst.at(index); + } + return nullptr; +} + +void AStackWidget::removeWidget(QWidget * widget) +{ + int index = indexOf(widget); + if (index >= 0) { + m_widgetLst.removeAll(widget); + emit widgetRemoved(index); + } +} + +void AStackWidget::setCurrentWidget(QWidget * widget) +{ + int index = indexOf(widget); + if (index >= 0 && m_curIndex != index) { + setCurrentIndex(index); + } +} + +void AStackWidget::setCurrentIndex(int index) +{ + if (index >= 0 && m_curIndex != index) { + m_lastIndex = m_curIndex; + m_curIndex = index; + moveAnimationStart(); + emit currentChanged(index); + } +} + +void AStackWidget::resizeEvent(QResizeEvent *event) +{ + QWidget::resizeEvent(event); + + int size = count(); + for (int i = 0; i < size; i++) { + m_widgetLst.at(i)->resize(this->width(), this->height()); + } + + if (m_moveAnimation->state() == QAbstractAnimation::Running) { + moveAnimationStart(); + } + else { + setWidgetsVisible(); + onValueChanged(0); + } +} + +void AStackWidget::onValueChanged(const QVariant &value) +{ + m_offset = value.toInt(); + m_widgetLst.at(m_curIndex)->move(m_offset, 0); + if (m_curIndex > m_lastIndex) { + m_widgetLst.at(m_lastIndex)->move(m_offset - this->width(), 0); + } else if (m_curIndex < m_lastIndex){ + m_widgetLst.at(m_lastIndex)->move(this->width() + m_offset, 0); + } +} + +void AStackWidget::moveAnimationStart() +{ + m_moveAnimation->stop(); + setWidgetsVisible(); + int startOffset = m_offset; + if (m_curIndex > m_lastIndex) { + if (startOffset == 0) startOffset = this->width(); + else startOffset = this->width() - qAbs(startOffset); + } + else { + if (startOffset == 0) startOffset = -this->width(); + else startOffset = qAbs(startOffset) - this->width(); + } + m_moveAnimation->setDuration(qAbs(startOffset) * m_duration / this->width()); + m_moveAnimation->setStartValue(startOffset); + m_moveAnimation->setEndValue(0); + m_moveAnimation->start(); +} + +void AStackWidget::setWidgetsVisible() +{ + int size = count(); + for (int i = 0; i < size; i++) { + if (m_lastIndex == i || m_curIndex == i) + m_widgetLst.at(i)->setVisible(true); + else { + m_widgetLst.at(i)->setVisible(false); + } + } +} + +void AStackWidget::onMoveFinished() +{ + +} diff --git a/astackwidget/astackwidget.h b/astackwidget/astackwidget.h new file mode 100644 index 0000000..41b3a2d --- /dev/null +++ b/astackwidget/astackwidget.h @@ -0,0 +1,52 @@ +#include + +class QPropertyAnimation; +class AStackWidget : public QWidget +{ + Q_OBJECT + +public: + AStackWidget(QWidget *parent); + ~AStackWidget(); + +signals: + void currentChanged(int index); + void widgetRemoved(int index); + +public: + int count() const; + int currentIndex() const; + int addWidget(QWidget *widget); + int indexOf(QWidget *widget) const; + int insertWidget(int index, QWidget *widget); + + QWidget *currentWidget() const; + QWidget *widget(int index) const; + + void removeWidget(QWidget *widget); + void setDuration(int duration); + +public slots: + void setCurrentIndex(int index); + void setCurrentWidget(QWidget *widget); + +private slots: + void onValueChanged(const QVariant &); + void onMoveFinished(); + +private: + void moveAnimationStart(); + void setWidgetsVisible(); + +protected: + void resizeEvent(QResizeEvent *event); + +private: + int m_offset; + int m_curIndex; + int m_lastIndex; + + int m_duration; + QPropertyAnimation *m_moveAnimation; + QList m_widgetLst; +}; diff --git a/astackwidget/astackwidget.pro b/astackwidget/astackwidget.pro new file mode 100644 index 0000000..b730c3e --- /dev/null +++ b/astackwidget/astackwidget.pro @@ -0,0 +1,23 @@ + +#------------------------------------------------- +# +# Project created by QtCreator 2021-02-19T09:21:04 +# +#------------------------------------------------- + +QT += core gui + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +TARGET = astackwidget +TEMPLATE = app +DESTDIR = $$PWD/../bin +CONFIG += warn_off + +SOURCES += main.cpp +SOURCES += astackwidget.cpp +HEADERS += astackwidget.h + +SOURCES += frmastackwidget.cpp +HEADERS += frmastackwidget.h +FORMS += frmastackwidget.ui diff --git a/astackwidget/astackwidget.pro.user b/astackwidget/astackwidget.pro.user new file mode 100644 index 0000000..ef6de47 --- /dev/null +++ b/astackwidget/astackwidget.pro.user @@ -0,0 +1,318 @@ + + + + + + EnvironmentId + {b1d4cc8c-364f-42c5-bde5-15245ae50f62} + + + ProjectExplorer.Project.ActiveTarget + 0 + + + ProjectExplorer.Project.EditorSettings + + true + false + true + + Cpp + + CppGlobal + + + + QmlJS + + QmlJSGlobal + + + 2 + UTF-8 + false + 4 + false + 80 + true + true + 1 + true + false + 0 + true + true + 0 + 8 + true + 1 + true + true + true + false + + + + ProjectExplorer.Project.PluginSettings + + + + ProjectExplorer.Project.Target.0 + + Desktop Qt 5.9.1 MinGW 32bit + Desktop Qt 5.9.1 MinGW 32bit + qt.591.win32_mingw53_kit + 0 + 0 + 0 + + D:/YutiangeWork/Qt-Control-master/FrmAStackWidget/build-astackwidget-Desktop_Qt_5_9_1_MinGW_32bit-Debug + + + true + qmake + + QtProjectManager.QMakeBuildStep + true + + false + false + false + + + true + Make + + Qt4ProjectManager.MakeStep + + false + + + + 2 + 构建 + + ProjectExplorer.BuildSteps.Build + + + + true + Make + + Qt4ProjectManager.MakeStep + + true + clean + + + 1 + 清理 + + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Debug + + Qt4ProjectManager.Qt4BuildConfiguration + 2 + true + + + D:/YutiangeWork/Qt-Control-master/FrmAStackWidget/build-astackwidget-Desktop_Qt_5_9_1_MinGW_32bit-Release + + + true + qmake + + QtProjectManager.QMakeBuildStep + false + + false + false + false + + + true + Make + + Qt4ProjectManager.MakeStep + + false + + + + 2 + 构建 + + ProjectExplorer.BuildSteps.Build + + + + true + Make + + Qt4ProjectManager.MakeStep + + true + clean + + + 1 + 清理 + + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Release + + Qt4ProjectManager.Qt4BuildConfiguration + 0 + true + + + D:/YutiangeWork/Qt-Control-master/FrmAStackWidget/build-astackwidget-Desktop_Qt_5_9_1_MinGW_32bit-Profile + + + true + qmake + + QtProjectManager.QMakeBuildStep + true + + false + true + false + + + true + Make + + Qt4ProjectManager.MakeStep + + false + + + + 2 + 构建 + + ProjectExplorer.BuildSteps.Build + + + + true + Make + + Qt4ProjectManager.MakeStep + + true + clean + + + 1 + 清理 + + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Profile + + Qt4ProjectManager.Qt4BuildConfiguration + 0 + true + + 3 + + + 0 + 部署 + + ProjectExplorer.BuildSteps.Deploy + + 1 + 在本地部署 + + ProjectExplorer.DefaultDeployConfiguration + + 1 + + + false + false + 1000 + + true + + false + false + false + false + true + 0.01 + 10 + true + 1 + 25 + + 1 + true + false + true + valgrind + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + 2 + + astackwidget + + Qt4ProjectManager.Qt4RunConfiguration:D:/YutiangeWork/Qt-Control-master/FrmAStackWidget/astackwidget/astackwidget.pro + true + + astackwidget.pro + false + + D:/YutiangeWork/Qt-Control-master/FrmAStackWidget/astackwidget/../bin + 3768 + false + true + false + false + true + + 1 + + + + ProjectExplorer.Project.TargetCount + 1 + + + ProjectExplorer.Project.Updater.FileVersion + 18 + + + Version + 18 + + diff --git a/astackwidget/frmastackwidget.cpp b/astackwidget/frmastackwidget.cpp new file mode 100644 index 0000000..be65222 --- /dev/null +++ b/astackwidget/frmastackwidget.cpp @@ -0,0 +1,38 @@ +#pragma execution_character_set("utf-8") + +#include "FrmAStackWidget.h" + +#include +#include + +FrmAStackWidget::FrmAStackWidget(QWidget *parent) + : QWidget(parent) +{ + ui.setupUi(this); + + QList colorlst; + colorlst << "#1abc9c"; + colorlst << "#2ecc71"; + colorlst << "#3498db"; + colorlst << "#9b59b6"; + colorlst << "#e74c3c"; + + QList btnlst; + btnlst << ui.pushButton_1; + btnlst << ui.pushButton_2; + btnlst << ui.pushButton_3; + btnlst << ui.pushButton_4; + btnlst << ui.pushButton_5; + + QButtonGroup *btnGroup = new QButtonGroup(this); + connect(btnGroup, static_cast(&QButtonGroup::buttonClicked), ui.aStackwidget, &AStackWidget::setCurrentIndex); + + for (int i = 0; i < 5; i++) { + QLabel *label = new QLabel(ui.aStackwidget); + label->setStyleSheet(QString("background-color:%1;color:#ffffff;").arg(colorlst.at(i))); + label->setText(QString::number(i + 1)); + label->setAlignment(Qt::AlignCenter); + int index = ui.aStackwidget->addWidget(label); + btnGroup->addButton(btnlst.at(i), index); + } +} diff --git a/astackwidget/frmastackwidget.h b/astackwidget/frmastackwidget.h new file mode 100644 index 0000000..8f9f80b --- /dev/null +++ b/astackwidget/frmastackwidget.h @@ -0,0 +1,13 @@ +#include +#include "ui_FrmAStackWidget.h" + +class FrmAStackWidget : public QWidget +{ + Q_OBJECT + +public: + FrmAStackWidget(QWidget *parent = Q_NULLPTR); + +private: + Ui::FrmAStackWidgetClass ui; +}; diff --git a/astackwidget/frmastackwidget.ui b/astackwidget/frmastackwidget.ui new file mode 100644 index 0000000..995c01c --- /dev/null +++ b/astackwidget/frmastackwidget.ui @@ -0,0 +1,94 @@ + + + FrmAStackWidgetClass + + + + 0 + 0 + 600 + 400 + + + + FrmAStackWidget + + + + 12 + + + 12 + + + 12 + + + 12 + + + 12 + + + + + + + PushButton1 + + + + + + + PushButton2 + + + + + + + PushButton3 + + + + + + + PushButton4 + + + + + + + PushButton5 + + + + + + + + + + 0 + 0 + + + + + + + + + + AStackWidget + QWidget +
astackwidget.h
+ 1 +
+
+ + +
diff --git a/astackwidget/main.cpp b/astackwidget/main.cpp new file mode 100644 index 0000000..b2897b2 --- /dev/null +++ b/astackwidget/main.cpp @@ -0,0 +1,30 @@ +#pragma execution_character_set("utf-8") +#include "frmastackwidget.h" + +#include +#include + +int main(int argc, char *argv[]) +{ + QApplication a(argc, argv); + a.setFont(QFont("Microsoft Yahei", 9)); + +#if (QT_VERSION <= QT_VERSION_CHECK(5,0,0)) +#if _MSC_VER + QTextCodec *codec = QTextCodec::codecForName("gbk"); +#else + QTextCodec *codec = QTextCodec::codecForName("utf-8"); +#endif + QTextCodec::setCodecForLocale(codec); + QTextCodec::setCodecForCStrings(codec); + QTextCodec::setCodecForTr(codec); +#else + QTextCodec *codec = QTextCodec::codecForName("utf-8"); + QTextCodec::setCodecForLocale(codec); +#endif + + FrmAStackWidget w; + w.setWindowTitle(QStringLiteral("动态StackWidget")); + w.show(); + return a.exec(); +}