├── snaps └── loadingsplash.png ├── src ├── main.cpp ├── mainwindow.cpp ├── mainwindow.h ├── mainwindow.ui └── forms │ └── splash_screen │ ├── splashscreen.h │ ├── circularprogress.h │ ├── splashscreen.cpp │ ├── circularprogress.cpp │ ├── ui_splash_screen.h │ └── splash_screen.ui ├── README.md └── LICENSE /snaps/loadingsplash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yet-Zio/Qt_CircularSplashScreen/HEAD/snaps/loadingsplash.png -------------------------------------------------------------------------------- /src/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main(int argc, char *argv[]) 5 | { 6 | QApplication a(argc, argv); 7 | SplashScreen w; 8 | w.show(); 9 | 10 | return a.exec(); 11 | } 12 | -------------------------------------------------------------------------------- /src/mainwindow.cpp: -------------------------------------------------------------------------------- 1 | #include "mainwindow.h" 2 | #include "ui_mainwindow.h" 3 | 4 | MainWindow::MainWindow(QWidget *parent) : 5 | QMainWindow(parent), 6 | ui(new Ui::MainWindow) 7 | { 8 | ui->setupUi(this); 9 | } 10 | 11 | MainWindow::~MainWindow() 12 | { 13 | delete ui; 14 | } 15 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Circular Splash Screen for Qt(C++) 2 | 3 | This was originally created in PySide by @Wanderson-Magalhaes in a tutorial video. 4 | 5 | The Splash Screen looked interesting to me and so I ported it to C++ in a reusable format. 6 | 7 | Hope it helps someone who's looking for a good splash screen for their application. Licensed under BSD-2 Clause. 8 | 9 | ## How it looks 10 | ![snap](snaps/loadingsplash.png) -------------------------------------------------------------------------------- /src/mainwindow.h: -------------------------------------------------------------------------------- 1 | #ifndef MAINWINDOW_H 2 | #define MAINWINDOW_H 3 | 4 | #include 5 | 6 | namespace Ui { 7 | class MainWindow; 8 | } 9 | 10 | class MainWindow : public QMainWindow 11 | { 12 | Q_OBJECT 13 | 14 | public: 15 | explicit MainWindow(QWidget *parent = nullptr); 16 | ~MainWindow(); 17 | 18 | private: 19 | Ui::MainWindow *ui; 20 | }; 21 | 22 | #endif // MainWindow_H 23 | -------------------------------------------------------------------------------- /src/mainwindow.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | MainWindow 6 | 7 | 8 | 9 | 0 10 | 0 11 | 800 12 | 600 13 | 14 | 15 | 16 | MainWindow 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /src/forms/splash_screen/splashscreen.h: -------------------------------------------------------------------------------- 1 | #ifndef SPLASHSCREEN_H 2 | #define SPLASHSCREEN_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | class SplashScreen : public QMainWindow 10 | { 11 | Q_OBJECT 12 | 13 | public: 14 | explicit SplashScreen(QWidget *parent = nullptr); 15 | ~SplashScreen(); 16 | 17 | public slots: 18 | void update(); 19 | 20 | private: 21 | int counter = 0; 22 | Ui_SplashScreen *ui; 23 | CircularProgress *mprogress; 24 | QTimer *mtimer; 25 | }; 26 | 27 | #endif // SPLASHSCREEN_H 28 | -------------------------------------------------------------------------------- /src/forms/splash_screen/circularprogress.h: -------------------------------------------------------------------------------- 1 | #ifndef CIRCULARPROGRESS_H 2 | #define CIRCULARPROGRESS_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | class CircularProgress: public QWidget 10 | { 11 | public: 12 | CircularProgress(QWidget *parent = nullptr); 13 | void set_value(int value); 14 | void add_shadow(bool enable); 15 | 16 | int value = 0; 17 | int width = 200; 18 | int height = 200; 19 | int progress_width = 10; 20 | bool progress_rounded_cap = true; 21 | bool enable_bg = true; 22 | QString bg_color = "#44475a"; 23 | QString progress_color = "#498BD1"; 24 | bool enable_text = true; 25 | int max_value = 100; 26 | QString font_family = "Segoe UI"; 27 | int font_size = 12; 28 | QString suffix = "%"; 29 | QString text_color = "#498BD1"; 30 | 31 | public slots: 32 | void change_value(int value){ 33 | set_value(value); 34 | } 35 | 36 | protected: 37 | void paintEvent(QPaintEvent *event); 38 | }; 39 | 40 | #endif // CIRCULARPROGRESS_H 41 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | BSD 2-Clause License 2 | 3 | Copyright (c) 2021, Yet-Zio 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | 1. Redistributions of source code must retain the above copyright notice, this 10 | list of conditions and the following disclaimer. 11 | 12 | 2. Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 20 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 22 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 23 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 24 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | -------------------------------------------------------------------------------- /src/forms/splash_screen/splashscreen.cpp: -------------------------------------------------------------------------------- 1 | #include "splashscreen.h" 2 | 3 | SplashScreen::SplashScreen(QWidget *parent) : QMainWindow(parent) 4 | { 5 | ui = new Ui_SplashScreen(); 6 | ui->setupUi(this); 7 | 8 | // remove title bar and make it translucent 9 | setWindowFlag(Qt::FramelessWindowHint); 10 | setAttribute(Qt::WA_TranslucentBackground); 11 | 12 | auto *progress = new CircularProgress(); 13 | mprogress = progress; 14 | progress->width = 270; 15 | progress->height = 270; 16 | progress->value = 0; 17 | progress->setFixedSize(progress->width, progress->height); 18 | progress->move(15, 15); 19 | progress->font_size = 40; 20 | progress->add_shadow(true); 21 | progress->bg_color = "#44475a"; 22 | progress->setParent(ui->centralwidget); 23 | progress->show(); 24 | 25 | // add drop shadow 26 | auto *shadow = new QGraphicsDropShadowEffect(); 27 | shadow->setBlurRadius(15); 28 | shadow->setXOffset(0); 29 | shadow->setYOffset(0); 30 | shadow->setColor(QColor(0, 0, 0, 80)); 31 | setGraphicsEffect(shadow); 32 | 33 | auto *timer = new QTimer(); 34 | mtimer = timer; 35 | QObject::connect(timer, SIGNAL(timeout()), this, SLOT(update())); 36 | timer->start(30); 37 | 38 | } 39 | 40 | SplashScreen::~SplashScreen(){ 41 | delete ui; 42 | } 43 | 44 | void SplashScreen::update(){ 45 | // set value to progress bar 46 | mprogress->set_value(counter); 47 | 48 | // close splash screen and open main app 49 | if(counter >= 100){ 50 | mtimer->stop(); 51 | auto *mainw = new MainWindow(); 52 | mainw->show(); 53 | close(); 54 | } 55 | 56 | // increase counter 57 | counter += 1; 58 | } 59 | -------------------------------------------------------------------------------- /src/forms/splash_screen/circularprogress.cpp: -------------------------------------------------------------------------------- 1 | #include "circularprogress.h" 2 | 3 | CircularProgress::CircularProgress(QWidget *parent) 4 | { 5 | resize(width, height); 6 | } 7 | 8 | void CircularProgress::paintEvent(QPaintEvent *event){ 9 | auto pnwidth = width - progress_width; 10 | auto pnheight = height - progress_width; 11 | auto margin = progress_width / 2; 12 | auto pnvalue = value * 360 / max_value; 13 | 14 | // painter 15 | auto *paint = new QPainter(); 16 | paint->begin(this); 17 | paint->setRenderHint(QPainter::Antialiasing); 18 | paint->setFont(QFont(font_family, font_size)); 19 | 20 | // create rect 21 | auto rect = QRect(0, 0, width, height); 22 | paint->setPen(Qt::NoPen); 23 | paint->drawRect(rect); 24 | 25 | // pen 26 | auto pen = QPen(); 27 | pen.setColor(QColor(progress_color)); 28 | pen.setWidth(progress_width); 29 | 30 | // bg pen 31 | auto penny = QPen(); 32 | penny.setColor(QColor(bg_color)); 33 | penny.setWidth(progress_width); 34 | 35 | // set round cap 36 | if(progress_rounded_cap){ 37 | pen.setCapStyle(Qt::RoundCap); 38 | penny.setCapStyle(Qt::RoundCap); 39 | } 40 | 41 | if(enable_bg){ 42 | paint->setPen(penny); 43 | paint->drawArc(margin, margin, pnwidth, pnheight, 0, 360 * 16); 44 | } 45 | 46 | // create arc/circular progress 47 | paint->setPen(pen); 48 | paint->drawArc(margin, margin, pnwidth, pnheight, -90 * 16, -pnvalue * 16); 49 | 50 | // create text 51 | if(enable_text){ 52 | pen.setColor(QColor(text_color)); 53 | paint->setPen(pen); 54 | paint->drawText(rect, Qt::AlignCenter, QString::number(value) + suffix); 55 | } 56 | 57 | // end 58 | paint->end(); 59 | } 60 | 61 | void CircularProgress::set_value(int value){ 62 | this->value = value; 63 | repaint(); // render progress bar after value is changed 64 | } 65 | 66 | void CircularProgress::add_shadow(bool enable){ 67 | if(enable){ 68 | auto *shadow = new QGraphicsDropShadowEffect(); 69 | shadow->setBlurRadius(15); 70 | shadow->setXOffset(0); 71 | shadow->setYOffset(0); 72 | shadow->setColor(QColor(0, 0, 0, 80)); 73 | setGraphicsEffect(shadow); 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /src/forms/splash_screen/ui_splash_screen.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************** 2 | ** Form generated from reading UI file 'splash_screenzhsQPN.ui' 3 | ** 4 | ** Created by: Qt User Interface Compiler version 5.15.0 5 | ** 6 | ** WARNING! All changes made in this file will be lost when recompiling UI file! 7 | ********************************************************************************/ 8 | 9 | #ifndef SPLASH_SCREENZHSQPN_H 10 | #define SPLASH_SCREENZHSQPN_H 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | 21 | QT_BEGIN_NAMESPACE 22 | 23 | class Ui_SplashScreen 24 | { 25 | public: 26 | QWidget *centralwidget; 27 | QVBoxLayout *verticalLayout; 28 | QFrame *container; 29 | QVBoxLayout *verticalLayout_2; 30 | QFrame *circle_bg; 31 | QVBoxLayout *verticalLayout_3; 32 | QFrame *texts; 33 | QVBoxLayout *verticalLayout_4; 34 | QGridLayout *gridLayout; 35 | QLabel *title; 36 | QFrame *empty; 37 | QLabel *loading; 38 | QFrame *frame_2; 39 | QVBoxLayout *verticalLayout_5; 40 | QLabel *version; 41 | 42 | void setupUi(QMainWindow *SplashScreen) 43 | { 44 | if (SplashScreen->objectName().isEmpty()) 45 | SplashScreen->setObjectName(QString::fromUtf8("SplashScreen")); 46 | SplashScreen->resize(300, 300); 47 | SplashScreen->setMinimumSize(QSize(300, 300)); 48 | SplashScreen->setMaximumSize(QSize(300, 300)); 49 | centralwidget = new QWidget(SplashScreen); 50 | centralwidget->setObjectName(QString::fromUtf8("centralwidget")); 51 | verticalLayout = new QVBoxLayout(centralwidget); 52 | verticalLayout->setSpacing(0); 53 | verticalLayout->setObjectName(QString::fromUtf8("verticalLayout")); 54 | verticalLayout->setContentsMargins(10, 10, 10, 10); 55 | container = new QFrame(centralwidget); 56 | container->setObjectName(QString::fromUtf8("container")); 57 | container->setFrameShape(QFrame::NoFrame); 58 | container->setFrameShadow(QFrame::Raised); 59 | verticalLayout_2 = new QVBoxLayout(container); 60 | verticalLayout_2->setSpacing(0); 61 | verticalLayout_2->setObjectName(QString::fromUtf8("verticalLayout_2")); 62 | verticalLayout_2->setContentsMargins(20, 20, 20, 20); 63 | circle_bg = new QFrame(container); 64 | circle_bg->setObjectName(QString::fromUtf8("circle_bg")); 65 | circle_bg->setStyleSheet(QString::fromUtf8("QFrame{\n" 66 | " background-color: #282a36;\n" 67 | " color: #f8f8f2;\n" 68 | " border-radius: 120px;\n" 69 | " font: 9pt \"Segoe UI\";\n" 70 | "}")); 71 | circle_bg->setFrameShape(QFrame::NoFrame); 72 | circle_bg->setFrameShadow(QFrame::Raised); 73 | verticalLayout_3 = new QVBoxLayout(circle_bg); 74 | verticalLayout_3->setSpacing(0); 75 | verticalLayout_3->setObjectName(QString::fromUtf8("verticalLayout_3")); 76 | verticalLayout_3->setContentsMargins(0, 0, 0, 0); 77 | texts = new QFrame(circle_bg); 78 | texts->setObjectName(QString::fromUtf8("texts")); 79 | texts->setMinimumSize(QSize(0, 90)); 80 | texts->setMaximumSize(QSize(16777215, 200)); 81 | texts->setStyleSheet(QString::fromUtf8("background: none;")); 82 | texts->setFrameShape(QFrame::NoFrame); 83 | texts->setFrameShadow(QFrame::Raised); 84 | verticalLayout_4 = new QVBoxLayout(texts); 85 | verticalLayout_4->setObjectName(QString::fromUtf8("verticalLayout_4")); 86 | verticalLayout_4->setContentsMargins(-1, 25, -1, -1); 87 | gridLayout = new QGridLayout(); 88 | gridLayout->setObjectName(QString::fromUtf8("gridLayout")); 89 | title = new QLabel(texts); 90 | title->setObjectName(QString::fromUtf8("title")); 91 | title->setMinimumSize(QSize(0, 30)); 92 | title->setAlignment(Qt::AlignCenter); 93 | 94 | gridLayout->addWidget(title, 0, 0, 1, 1); 95 | 96 | empty = new QFrame(texts); 97 | empty->setObjectName(QString::fromUtf8("empty")); 98 | empty->setMinimumSize(QSize(0, 80)); 99 | empty->setFrameShape(QFrame::NoFrame); 100 | empty->setFrameShadow(QFrame::Raised); 101 | 102 | gridLayout->addWidget(empty, 1, 0, 1, 1); 103 | 104 | loading = new QLabel(texts); 105 | loading->setObjectName(QString::fromUtf8("loading")); 106 | loading->setAlignment(Qt::AlignCenter); 107 | 108 | gridLayout->addWidget(loading, 3, 0, 1, 1); 109 | 110 | frame_2 = new QFrame(texts); 111 | frame_2->setObjectName(QString::fromUtf8("frame_2")); 112 | frame_2->setFrameShape(QFrame::NoFrame); 113 | frame_2->setFrameShadow(QFrame::Raised); 114 | verticalLayout_5 = new QVBoxLayout(frame_2); 115 | verticalLayout_5->setSpacing(0); 116 | verticalLayout_5->setObjectName(QString::fromUtf8("verticalLayout_5")); 117 | verticalLayout_5->setContentsMargins(0, 0, 0, 0); 118 | version = new QLabel(frame_2); 119 | version->setObjectName(QString::fromUtf8("version")); 120 | version->setMinimumSize(QSize(100, 24)); 121 | version->setMaximumSize(QSize(100, 24)); 122 | version->setStyleSheet(QString::fromUtf8("QLabel{\n" 123 | " color: rgb(151, 159, 200);\n" 124 | " background-color: rgb(68,71,90);\n" 125 | " border-radius: 12px;\n" 126 | "}")); 127 | version->setAlignment(Qt::AlignCenter); 128 | 129 | verticalLayout_5->addWidget(version, 0, Qt::AlignHCenter); 130 | 131 | 132 | gridLayout->addWidget(frame_2, 2, 0, 1, 1); 133 | 134 | 135 | verticalLayout_4->addLayout(gridLayout); 136 | 137 | 138 | verticalLayout_3->addWidget(texts); 139 | 140 | 141 | verticalLayout_2->addWidget(circle_bg); 142 | 143 | 144 | verticalLayout->addWidget(container); 145 | 146 | SplashScreen->setCentralWidget(centralwidget); 147 | 148 | retranslateUi(SplashScreen); 149 | 150 | QMetaObject::connectSlotsByName(SplashScreen); 151 | } // setupUi 152 | 153 | void retranslateUi(QMainWindow *SplashScreen) 154 | { 155 | SplashScreen->setWindowTitle(QCoreApplication::translate("SplashScreen", "Loading...", nullptr)); 156 | title->setText(QCoreApplication::translate("SplashScreen", "Sample App", nullptr)); 157 | loading->setText(QCoreApplication::translate("SplashScreen", "loading...", nullptr)); 158 | version->setText(QCoreApplication::translate("SplashScreen", "v1.0.0 - Beta", nullptr)); 159 | } // retranslateUi 160 | 161 | }; 162 | 163 | namespace Ui { 164 | class SplashScreen: public Ui_SplashScreen {}; 165 | } // namespace Ui 166 | 167 | QT_END_NAMESPACE 168 | 169 | #endif // SPLASH_SCREENZHSQPN_H 170 | -------------------------------------------------------------------------------- /src/forms/splash_screen/splash_screen.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | SplashScreen 4 | 5 | 6 | 7 | 0 8 | 0 9 | 300 10 | 300 11 | 12 | 13 | 14 | 15 | 300 16 | 300 17 | 18 | 19 | 20 | 21 | 300 22 | 300 23 | 24 | 25 | 26 | Loading... 27 | 28 | 29 | 30 | 31 | 0 32 | 33 | 34 | 10 35 | 36 | 37 | 10 38 | 39 | 40 | 10 41 | 42 | 43 | 10 44 | 45 | 46 | 47 | 48 | QFrame::NoFrame 49 | 50 | 51 | QFrame::Raised 52 | 53 | 54 | 55 | 0 56 | 57 | 58 | 20 59 | 60 | 61 | 20 62 | 63 | 64 | 20 65 | 66 | 67 | 20 68 | 69 | 70 | 71 | 72 | QFrame{ 73 | background-color: #282a36; 74 | color: #f8f8f2; 75 | border-radius: 120px; 76 | font: 9pt "Segoe UI"; 77 | } 78 | 79 | 80 | QFrame::NoFrame 81 | 82 | 83 | QFrame::Raised 84 | 85 | 86 | 87 | 0 88 | 89 | 90 | 0 91 | 92 | 93 | 0 94 | 95 | 96 | 0 97 | 98 | 99 | 0 100 | 101 | 102 | 103 | 104 | 105 | 16777215 106 | 180 107 | 108 | 109 | 110 | background: none; 111 | 112 | 113 | QFrame::NoFrame 114 | 115 | 116 | QFrame::Raised 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 0 126 | 30 127 | 128 | 129 | 130 | Sample App 131 | 132 | 133 | Qt::AlignCenter 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 0 142 | 80 143 | 144 | 145 | 146 | QFrame::NoFrame 147 | 148 | 149 | QFrame::Raised 150 | 151 | 152 | 153 | 154 | 155 | 156 | loading... 157 | 158 | 159 | Qt::AlignCenter 160 | 161 | 162 | 163 | 164 | 165 | 166 | QFrame::NoFrame 167 | 168 | 169 | QFrame::Raised 170 | 171 | 172 | 173 | 0 174 | 175 | 176 | 0 177 | 178 | 179 | 0 180 | 181 | 182 | 0 183 | 184 | 185 | 0 186 | 187 | 188 | 189 | 190 | 191 | 100 192 | 24 193 | 194 | 195 | 196 | 197 | 100 198 | 24 199 | 200 | 201 | 202 | QLabel{ 203 | color: rgb(151, 159, 200); 204 | background-color: rgb(68,71,90); 205 | border-radius: 12px; 206 | } 207 | 208 | 209 | v1.0.0 - Beta 210 | 211 | 212 | Qt::AlignCenter 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | --------------------------------------------------------------------------------