Qt Splash Screen not showing - c++

I have this code, I want it to show a splash screen since it will be bigger, having had made a kind of timer so it is possible to see the splash screen working. The problem is I don't see the splash screen, but the code will be running while the splash screen doesn't appear, sending me directly to the main window without showing the splas screen.
Here's my code.
main.cpp
#include <iostream>
#include <QApplication>
#include <quazip/quazip.h>
#include "splashwindow.h"
#include "mainwindow.h"
#include "database.h"
int main(int argc, char *argv[])
{
/* Define the app */
QApplication app(argc, argv);
/* Define the splash screen */
SplashWindow splashW;
/* Show the splash screen */
splashW.show();
/* Download the database */
/* Define the database */
Downloader db;
/* Donwloading the database */
db.doDownload();
/* Unzip the database */
/* Define the database */
//Unzipper uz;
//uz.Unzip();
for(int i = 0; i < 1000000; i++)
{
cout << i << endl;
}
/* Close the splash screen */
splashW.hide();
splashW.close();
/* Define the main screen */
MainWindow mainW;
/* Show the main window */
mainW.showMaximized();
return app.exec();
}
splashwindow.cpp
#include <iostream>
#include <QStyle>
#include <QDesktopWidget>
#include "splashwindow.h"
#include "ui_splashwindow.h"
#include "database.h"
/* Splash screen constructor */
SplashWindow::SplashWindow (QWidget *parent) :
QMainWindow(parent), ui(new Ui::SplashWindow)
{
ui->setupUi(this);
/* Set window's flags as needed for a splash screen */
this->setWindowFlags(Qt::CustomizeWindowHint | Qt::WindowStaysOnTopHint | Qt::SplashScreen);
}
/* Splash screen destructor */
SplashWindow::~SplashWindow()
{
delete ui;
}
splashwindow.h
#ifndef SPLASHWINDOW_H
#define SPLASHWINDOW_H
#include <QMainWindow>
namespace Ui {
class SplashWindow;
}
class SplashWindow : public QMainWindow
{
Q_OBJECT
public:
explicit SplashWindow(QWidget *parent = 0);
~SplashWindow();
private:
Ui::SplashWindow *ui;
};
#endif // SPLASHWINDOW_H
The commands run in such way that the splash screen will not appear before they are run, not showing, wich I can't find a way to fix.
[EDIT] The part of the code corresponding to the closure was misplaced, though it still doesn't work after putting it correctly.

You have at least two issues ongoing:
You send the main thread into a blocking loop and it has no way to process events including the show of your window. That requires some event processing, hence you would need to call the following method before your while loop:
void QCoreApplication::processEvents(QEventLoop::ProcessEventsFlags flags = QEventLoop::AllEvents) [static]
I would suggest to use QSplashScreen in the first as per documentation. Note the explicit call for processing the events in the example. The code below works fine for me.
main.cpp
#include <QApplication>
#include <QPixmap>
#include <QMainWindow>
#include <QSplashScreen>
#include <QDebug>
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
QPixmap pixmap("splash.png");
QSplashScreen splash(pixmap);
splash.show();
app.processEvents();
for (int i = 0; i < 500000; ++i)
qDebug() << i;
QMainWindow window;
window.show();
splash.finish(&window);
return app.exec();
}
main.pro
TEMPLATE = app
TARGET = main
greaterThan(QT_MAJOR_VERSION, 4):QT += widgets
SOURCES += main.cpp

What has worked for me,
where the splash worked on earlier versions of Qt but not since 5.6 was to comment out the setWindowFlags statements.

Related

Painting a QVideoFrame on a QVideoWidget with QT6

I'd like to process the stream of my webcam frame by frame with QT6. I've checked the internet but since QTMultimedia was heavily reworked with QT6, and since QT6 is pretty new, all the documentation/questions available are outdated.
So, In order to achieve my goal, I'm using a QMediaCaptureSession with a camera set on QMediaDevices::defaultVideoInput(). I checked that this was working by setting the video output of the QMediaCaptureSession to a QVideoWidget with m_session.setVideoOutput(ui->videowidget);, and it's working fine, except that I can't process the frames (basically, it's rendering my webcam on the QVideoWidget).
Now, to process the frames, I have to use a QVideoSink as far as I understand the documentation here and there. So I replaced m_session.setVideoOutput(ui->videowidget); with m_session.setVideoSink(&mysink);, where mysink is a QVideoSink.
Then, since I want to process the frames, I'm connecting the videoFrameChanged signal of mysink to a function processVideoFrame where I want to do 2 things :
process the current frame
render the result on the UI, ideally on ui->videowidget
This is the point where I'm struggling. I do not understand how to use the paint function of the class QVideoFrame to render the processed frame on the QVideoWidget. More precisely :
I do not understand how I'm supposed to instantiate the QPainter. I tried a straightforward new QPainter(ui->videowidget) but it ends up in a QWidget::paintEngine: Should no longer be called exception and nothing is rendered
I do not understand what is actually representing the second parameter rect of QVideoFrame::paint?
I made a MWE, code is below.
mwe_videosinkpainting.h
#ifndef MWE_VIDEOSINKPAINTING_H
#define MWE_VIDEOSINKPAINTING_H
#include <QMainWindow>
#include <QMediaCaptureSession>
#include <QMediaDevices>
#include <QCamera>
#include <QVideoSink>
#include <QPainter>
QT_BEGIN_NAMESPACE
namespace Ui { class MWE_VideoSinkPainting; }
QT_END_NAMESPACE
class MWE_VideoSinkPainting : public QMainWindow
{
Q_OBJECT
public:
MWE_VideoSinkPainting(QWidget *parent = nullptr);
~MWE_VideoSinkPainting();
private slots:
void processVideoFrame();
private:
Ui::MWE_VideoSinkPainting *ui;
QVideoSink mysink;
QMediaCaptureSession m_session;
QScopedPointer<QCamera> m_camera;
};
#endif // MWE_VIDEOSINKPAINTING_H
mwe_videosinking.cpp
#include "mwe_videosinkpainting.h"
#include "ui_mwe_videosinkpainting.h"
MWE_VideoSinkPainting::MWE_VideoSinkPainting(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MWE_VideoSinkPainting)
{
ui->setupUi(this);
m_camera.reset(new QCamera(QMediaDevices::defaultVideoInput()));
m_session.setCamera(m_camera.data());
//m_session.setVideoOutput(ui->videowidget);
connect(&mysink, &QVideoSink::videoFrameChanged, this, &MWE_VideoSinkPainting::processVideoFrame);
m_session.setVideoSink(&mysink);
m_camera->start();
}
MWE_VideoSinkPainting::~MWE_VideoSinkPainting()
{
delete ui;
}
void MWE_VideoSinkPainting::processVideoFrame()
{
QVideoFrame videoframe = mysink.videoFrame();
if(videoframe.map(QVideoFrame::ReadOnly))
{
//This is the part I'm struggling to understand and achieve
videoframe.paint(new QPainter(ui->videowidget), QRectF(0.0f,0.0f,100.0f,100.0f), QVideoFrame::PaintOptions());
videoframe.unmap();
}
}
main.cpp
#include "mwe_videosinkpainting.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MWE_VideoSinkPainting w;
w.show();
return a.exec();
}
ui_mwe_videosinkpainting.h (just so that you have the whole code, it has no value for the question)
#ifndef UI_MWE_VIDEOSINKPAINTING_H
#define UI_MWE_VIDEOSINKPAINTING_H
#include <QtCore/QVariant>
#include <QtMultimediaWidgets/QVideoWidget>
#include <QtWidgets/QApplication>
#include <QtWidgets/QGridLayout>
#include <QtWidgets/QHBoxLayout>
#include <QtWidgets/QMainWindow>
#include <QtWidgets/QMenuBar>
#include <QtWidgets/QStatusBar>
#include <QtWidgets/QWidget>
QT_BEGIN_NAMESPACE
class Ui_MWE_VideoSinkPainting
{
public:
QWidget *centralwidget;
QGridLayout *gridLayout;
QVideoWidget *videowidget;
QHBoxLayout *horizontalLayout;
QMenuBar *menubar;
QStatusBar *statusbar;
void setupUi(QMainWindow *MWE_VideoSinkPainting)
{
if (MWE_VideoSinkPainting->objectName().isEmpty())
MWE_VideoSinkPainting->setObjectName(QString::fromUtf8("MWE_VideoSinkPainting"));
MWE_VideoSinkPainting->resize(800, 600);
centralwidget = new QWidget(MWE_VideoSinkPainting);
centralwidget->setObjectName(QString::fromUtf8("centralwidget"));
gridLayout = new QGridLayout(centralwidget);
gridLayout->setObjectName(QString::fromUtf8("gridLayout"));
videowidget = new QVideoWidget(centralwidget);
videowidget->setObjectName(QString::fromUtf8("videowidget"));
horizontalLayout = new QHBoxLayout(videowidget);
horizontalLayout->setObjectName(QString::fromUtf8("horizontalLayout"));
gridLayout->addWidget(videowidget, 0, 0, 1, 1);
MWE_VideoSinkPainting->setCentralWidget(centralwidget);
menubar = new QMenuBar(MWE_VideoSinkPainting);
menubar->setObjectName(QString::fromUtf8("menubar"));
menubar->setGeometry(QRect(0, 0, 800, 21));
MWE_VideoSinkPainting->setMenuBar(menubar);
statusbar = new QStatusBar(MWE_VideoSinkPainting);
statusbar->setObjectName(QString::fromUtf8("statusbar"));
MWE_VideoSinkPainting->setStatusBar(statusbar);
retranslateUi(MWE_VideoSinkPainting);
QMetaObject::connectSlotsByName(MWE_VideoSinkPainting);
} // setupUi
void retranslateUi(QMainWindow *MWE_VideoSinkPainting)
{
MWE_VideoSinkPainting->setWindowTitle(QCoreApplication::translate("MWE_VideoSinkPainting", "MWE_VideoSinkPainting", nullptr));
} // retranslateUi
};
namespace Ui {
class MWE_VideoSinkPainting: public Ui_MWE_VideoSinkPainting {};
} // namespace Ui
QT_END_NAMESPACE
#endif // UI_MWE_VIDEOSINKPAINTING_H
The answer is quite straightforward : you can use setVideoSink AND setVideoOutput.
The code I gave in OP is good, you just have to uncomment setVideoOutput(ui->videowidget); of mwe_videosinking.cpp and to call setVideoSink BEFORE calling setVideoOutput
Since I cannot format code in a comment...
So, you mean change this...
ui->setupUi(this);
m_camera.reset(new QCamera(QMediaDevices::defaultVideoInput()));
m_session.setCamera(m_camera.data());
//m_session.setVideoOutput(ui->videowidget);
connect(&mysink, &QVideoSink::videoFrameChanged, this, &MWE_VideoSinkPainting::processVideoFrame);
m_session.setVideoSink(&mysink);
m_camera->start();
...to this?
ui->setupUi(this);
m_camera.reset(new QCamera(QMediaDevices::defaultVideoInput()));
m_session.setCamera(m_camera.data());
m_session.setVideoSink(&mysink);
m_session.setVideoOutput(ui->videowidget);
connect(&mysink, &QVideoSink::videoFrameChanged, this, &MWE_VideoSinkPainting::processVideoFrame);
m_camera->start();
I did this and I am still only getting black in my videoWidget.

Qt: cursor blinking cause repaint of parent widget?

Bellow you can see minimal example code to demonstrate problem.
If you run it and give focus to QLineEdit, you get output every second: paintEvent, paintEvent and so on.
I can not understand why MyW::paintEvent called on every
cursor blinking in child widget? As you see I do not configure QLineEdit,
by default on my linux box it have no transparent elements,
but still for some reason cursor cause all widgets to redraw their content?
#include <QApplication>
#include <QWidget>
#include <QPaintEvent>
#include <QPainter>
#include <QLineEdit>
class MyW final : public QWidget {
public:
MyW() {
//setAutoFillBackground(false);
}
void paintEvent(QPaintEvent *e) {
e->accept();
qDebug("paintEvent");
QPainter painter{this};
painter.fillRect(rect(), Qt::green);
}
};
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
MyW w;
w.resize(600, 600);
w.show();
auto le = new QLineEdit{&w};
le->show();
return app.exec();
}

Overlay while loading page into QWebView

Let's say we have a barebones QWebView:
#include <QApplication>
#include <QWebView>
int main(int argc, char** argv)
{
QApplication app(argc, argv);
QWebView view;
view.show();
view.setUrl(QUrl("http://google.com"));
return app.exec();
}
How can I display a graphic overlay, preferably fullscreen with transparency and minimal animation (like timer/beachball/etc.) from when the page starts loading till it's finished? Should also be triggered when url changes from within the QWebView.
You can use the LoadingOverlay class provided in this answer to draw an overlay over any QWidget. In your case, show the overlay on top of the QWebView when the signal loadStarted is triggered and hide it, when the signal loadFinished is triggered.
The following code should get you started. I put the code from the linked answer into overlay.h, the subclass of QWebView which handles the showing/hiding of the overlay is in webview.h:
webview.h
#include "overlay.h"
#include <QWebView>
class WebView : public QWebView
{
Q_OBJECT
public:
WebView(QWidget * parent) : QWebView(parent)
{
overlay = new LoadingOverlay(parent);
connect(this,SIGNAL(loadFinished(bool)),this,SLOT(hideOverlay()));
connect(this,SIGNAL(loadStarted()),this,SLOT(showOverlay()));
}
~WebView()
{
}
public slots:
void showOverlay()
{
overlay->show();
}
void hideOverlay()
{
overlay->hide();
}
private:
LoadingOverlay* overlay;
};
main.cpp
#include <QApplication>
#include "overlay.h"
#include "webview.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
ContainerWidget base;
Webview w(&base);
base.show();
w.load(QUrl("http://google.com"));
return a.exec();
}

QT 5.3 Mac Full Screen

I'm trying to set my application to full screen and back in Qt 5.3, but I'm running into some issues on Mac. When I use showFullScreen(), it goes into full screen as expected. It uses the standard Mac full screen mode where it opens in a separate desktop/space. However, when I call showNormal() to return from full screen mode, the application window just disappears and I'm left with a gray background. I need to swipe in order to return to the regular desktop where the application is.
Is this a bug in Qt or am I doing something wrong? I'm on OS X 10.9.3.
I had similar problems with Qt 5.2 on Mac OS X (but not Qt 4.8). This seems to fix it:
if ( showFullScreen )
{
widget->setParent( NULL );
widget->showFullScreen();
}
else
{
// changing the order of the showNormal() and setParent() results in a grey screen in Qt 5 on Mac
widget->showNormal();
widget->setParent( widgetParent ); // reset the original parent
}
I am not sure if this or this relate to your problem. But it seems that calls to showFullScreen() and showNormal() is buggy on Mac.
You can change the calls to showFullScreen() and showNormal() with setWindowState().
showFullScreen(); can be changed to
setWindowState(windowState() | Qt::WindowFullScreen);
And showNormal(); can be changed to
setWindowState(windowState() & ~Qt::WindowFullScreen);
Here's a trivial example application that works correctly on my system (Qt 5.3.1, MacOS/X 10.9.5). Does it work correctly for you also? If so, try and figure out what is different between this program and your program.
You might also try calling show(), raise(), and activateWindow() after calling showNormal() and see if those things help.
// MyWindow.h
#ifndef MYWINDOW_H
#define MYWINDOW_H
#include <QAction>
#include <QLabel>
#include <QTimer>
#include <QTime>
#include <QMainWindow>
class MyWindow : public QMainWindow
{
Q_OBJECT
public:
MyWindow();
private slots:
void goFS();
void goNormal();
private:
QAction * fsAct;
QAction * normAct;
};
#endif // MYWINDOW_H
... and the .cpp file:
// MyWindow.cpp
#include <QApplication>
#include <QMenuBar>
#include <QMenu>
#include <QAction>
#include "MyWindow.h"
MyWindow :: MyWindow()
{
fsAct = new QAction(tr("Full Screen Mode"), this);
connect(fsAct, SIGNAL(triggered()), this, SLOT(goFS()));
normAct = new QAction(tr("Normal Mode"), this);
connect(normAct, SIGNAL(triggered()), this, SLOT(goNormal()));
normAct->setEnabled(false);
QMenuBar * mb = menuBar();
QMenu * modeMenu = mb->addMenu(tr("ScreenMode"));
modeMenu->addAction(fsAct);
modeMenu->addAction(normAct);
}
void MyWindow :: goFS()
{
normAct->setEnabled(true);
fsAct->setEnabled(false);
showFullScreen();
}
void MyWindow :: goNormal()
{
normAct->setEnabled(false);
fsAct->setEnabled(true);
showNormal();
}
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MyWindow scr;
scr.show();
return a.exec();
}

Frameless and transparent window qt5

I'm quite new to qt and c++ and I've encountered a problem that I can't seem to figure out. I'm wanting to open a frameless and transparent window when I click a button on the main ui. I've got the code working to open a new window when I press a button on the main ui but I can't seem to get the frameless and transparent part working.
Here is the source codes for the small program that I wrote to learn this
main.cpp
#include "learnwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
LearnWindow w;
w.show();
return a.exec();
}
Here is the LearnWindow.h
#ifndef LEARNWINDOW_H
#define LEARNWINDOW_H
#include <QMainWindow>
#include <transwindow.h>
namespace Ui {
class LearnWindow;
}
class LearnWindow : public QMainWindow
{
Q_OBJECT
public:
explicit LearnWindow(QWidget *parent = 0);
~LearnWindow();
private slots:
void on_pushButton_clicked();
private:
Ui::LearnWindow *ui;
TransWindow *winTrans;
public slots:
void openTrans();
};
#endif // LEARNWINDOW_H
Here is learnwindow.cpp
#include "learnwindow.h"
#include "ui_learnwindow.h"
LearnWindow::LearnWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::LearnWindow)
{
ui->setupUi(this);
}
LearnWindow::~LearnWindow()
{
delete ui;
}
void LearnWindow::openTrans()
{
winTrans = new TransWindow (this);
//winTrans->setWindowTitle("NewWin");
// winTrans->setWindowFlags(Qt::FramelessWindowHint | Qt::X11BypassWindowManagerHint);
//winTrans->setAttribute(Qt::WA_TranslucentBackground,true);
//winTrans->setAutoFillBackground(false);
//winTrans->setStyleSheet("background:transparent;");
winTrans->show();
}
void LearnWindow::on_pushButton_clicked()
{
openTrans();
}
Here is the transwindow.h
#ifndef TRANSWINDOW_H
#define TRANSWINDOW_H
#include <QDialog>
namespace Ui {
class TransWindow;
}
class TransWindow : public QDialog
{
Q_OBJECT
public:
explicit TransWindow(QWidget *parent = 0);
//setWindowFlags(windowFlags()| Qt::FramelessWindowHint);
~TransWindow();
private:
Ui::TransWindow *ui;
};
#endif // TRANSWINDOW_H
And here is transwindow.cpp
#include "transwindow.h"
#include "ui_transwindow.h"
TransWindow::TransWindow(QWidget *parent) :
QDialog(parent),
ui(new Ui::TransWindow)
{
//setWindowTitle("NewWin");
//setWindowFlags(Qt::FramelessWindowHint);
//setAttribute(Qt::WA_TranslucentBackground,true);
ui->setupUi(this);
}
TransWindow::~TransWindow()
{
delete ui;
}
In the different source codes you'll see commented out lines which is the different things that I've tried. For the most part the problem is, if I un-comment out any of the lines that try to set the "Qt::FramlessWindowHint" the program runs normally but never opens a new window when I click the button on the main ui.
If I un-comment out any of the lines where I set the "Qt::WA_TranslucentBackground" the new window will open up when when the button is pressed in the main ui but the background of the new window is black, not transparent.
Other info that may be pertinent:
linux: ubunto 12.04
qt 5.0.2 (64-bit)
qt creator 2.7.1
Try this:
setWindowFlags(Qt::Widget | Qt::FramelessWindowHint);
setParent(0); // Create TopLevel-Widget
setAttribute(Qt::WA_NoSystemBackground, true);
setAttribute(Qt::WA_TranslucentBackground, true);
setAttribute(Qt::WA_PaintOnScreen); // not needed in Qt 5.2 and up