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();
}
Related
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.
I migrated some code from Qt 5.6.0 to 5.12.0. Suprisingly, I'm getting lots of warnings related to QWindowsWindow::setGeometry. Whenever a dialog is shown on top of another, I get this warning.
I could isolate the problem in a MCVE, it's very simple and minimal, all parenting look good, however, we get the warning when button is pressed:
QWindowsWindow::setGeometry: Unable to set geometry 132x30+682+303 on QWidgetWindow/'QDialogClassWindow'. Resulting geometry: 132x42+682+303 (frame: 4, 28, 4, 4, custom margin: 0, 0, 0, 0, minimum size: 116x42, maximum size: 16777215x16777215).
main.cpp:
#include <QApplication>
#include "mainframe.h"
#include <qDebug>
void MessageOutput( QtMsgType type, const QMessageLogContext &context, const QString &msg)
{
qDebug() << msg;
}
int main( int argc, char* argv[] )
{
QApplication app(argc, argv);
qInstallMessageHandler(MessageOutput);
MainFrame wnd;
wnd.show();
return app.exec();
}
mainframe.h:
#include <QMainWindow>
class QPushButton;
class MainFrame : public QMainWindow
{
Q_OBJECT
public:
MainFrame();
public slots:
void showPopup();
private:
QPushButton* button;
};
mainframe.cpp:
#include "mainframe.h"
#include <QDialog>
#include <QLabel>
#include <QPushButton>
#include <QVBoxLayout>
MainFrame::MainFrame()
{
QWidget* widget = new QWidget( this );
widget->setLayout( new QVBoxLayout( widget ) );
QPushButton* pTextButton = new QPushButton( "Show popup", widget );
widget->layout()->addWidget( pTextButton );
connect( pTextButton, SIGNAL(clicked()), this, SLOT(showPopup()) );
setCentralWidget( widget );
}
void MainFrame::showPopup()
{
QDialog dlg( this );
dlg.setLayout( new QVBoxLayout() );
dlg.layout()->addWidget( new QLabel("popup message",&dlg) );
dlg.exec();
}
I see the issue under Windows 7 and 10. Am I doing anything wrong?
I know the warning can be removed by setting setMinimumSize (see https://stackoverflow.com/a/31231069/3336423), but why should we do this for every widget we create? Is there a way to fix that for good?
As you mentioned, this problem occurs only in Windows: the QWindowsWindow class is part of the windows platform plugin. Looking at Qt's source code (qwindowswindow.cpp#QWindowsWindow::setGeometry) there is no direct way to pause that specific message.
The only global solution I can think of right now is to filter the warning messages using a message handler:
void myMessageOutput(QtMsgType type, const QMessageLogContext& context, const QString& msg)
{
if (type != QtWarningMsg || !msg.startsWith("QWindowsWindow::setGeometry")) {
QByteArray localMsg = msg.toLocal8Bit();
fprintf(stdout, localMsg.constData());
}
}
int main(int argc, char* argv[])
{
qInstallMessageHandler(myMessageOutput);
QApplication a(argc, argv);
// ...
}
UPDATE
One of the problems is that Windows adds its own buttons to the frame. In your example the dialog adds three buttons: the system button (the icon, top-left corner), the help button and the close button. The help and close buttons have a fixed size, which happens to be larger than the QDialog's frame (which is computed as the maximum between the requested size and minimumSize). This then generates the warning: your requested size doesn't match the one created by Windows:
If you remove the help button, for example (dlg.setWindowFlags(dlg.windowFlags() & ~Qt::WindowContextHelpButtonHint);), the warning disappears without setting a minimum size for the window. A manual action must be taken for each dialog displayed, but I think it is easier to automatize than the minimum size (through a factory maybe?):
The issue was reported to Qt:
https://bugreports.qt.io/browse/QTBUG-73258
To the code in OP is OK, it's just a Qt bug.
It's marked as "P2 Important", so hopefully it should be fixed in a next release.
Update: It's still not fixed in Qt 6.2.2...
I have a parent container (MyCartParentWidget) with translucent background, inside which I have to draw a child widget (MyCart) with an image background (this image is in portrait, this image is in landscape), also drawn with translucent background, and both being QLabels. There is a button clicking on which, the child widget toggles its dimensions (resetCartStyle), i.e it goes from portrait to landscape mode and vice versa. Problem is, when it toggles, the original imprint stays back, i.e, this is the original pic where it is in 'portrait' mode:
Then when I switch to 'landscape' mode, it does shift, but the original 'portrait' mode stays back:
This is my code:
main.cpp:
#include <QApplication>
#include "MyCartParentWidget.hpp"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MyCartParentWidget p;
p.move(370,10);
p.show();
return a.exec();
}
MyCart.cpp:
#include "MyCart.hpp"
#include <QPainter>
MyCart::MyCart(QWidget *parent): QLabel(parent)
{
setAttribute(Qt::WA_TranslucentBackground);
fPixMap.load("/Users/attitude/Desktop/RnSghvV.png");
setStyleSheet("background-color: rgba(0,0,0,255);");
setFixedSize(325,400);
}
void MyCart::paintEvent(QPaintEvent *)
{
QPainter p(this);
p.setRenderHint(QPainter::SmoothPixmapTransform);
p.drawPixmap(0,0,width(),height(),fPixMap);
}
void MyCart::resetCartStyle(QString url, int w, int h)
{
setFixedSize(w,h);
fPixMap.load(url);
this->update();
}
MyCart.hpp:
#pragma once
#include <QLabel>
#include <QPaintEvent>
#include <QPixmap>
class MyCart: public QLabel
{
public:
MyCart(QWidget*);
virtual void paintEvent(QPaintEvent *);
QPixmap fPixMap;
void resetCartStyle(QString, int w, int h);
};
MyCartParentWidget.cpp:
#include "MyCartParentWidget.hpp"
#include <QPushButton>
MyCartParentWidget::MyCartParentWidget()
{
setFixedSize(800,700);
setWindowFlags(Qt::FramelessWindowHint);
setAttribute(Qt::WA_TranslucentBackground);
setStyleSheet("background-color: none;");
fLayout = new QHBoxLayout();
setLayout(fLayout);
fLayout->setContentsMargins(0,0,0,0);
fLayout->setSpacing(0);
fLayout->setMargin(0);
fLayout->setAlignment(Qt::AlignLeft | Qt:: AlignTop);
i = 0;
fCart = new MyCart(this);
fLayout->addWidget(fCart);
QPushButton* p = new QPushButton(this);
p->setText("Toggle");
p->move(0,650);
connect(p,SIGNAL(clicked(bool)),this,SLOT(clickedSlot()));
}
void MyCartParentWidget::clickedSlot()
{
if (i == 0)
{
//enter landscape mode
i = 1;
fCart->resetCartStyle("/Users/attitude/Desktop/foo.png",400,325);
}
else
{
//enter portrait mode
i = 0;
fCart->resetCartStyle("/Users/attitude/Desktop/RnSghvV.png",325,400);
}
}
MyCartParentWidget.hpp:
#pragma once
#include <QLabel>
#include <QHBoxLayout>
#include "MyCart.hpp"
class MyCartParentWidget: public QLabel
{
Q_OBJECT
public:
MyCartParentWidget();
QHBoxLayout* fLayout;
MyCart *fCart;
int i;
private slots:
void clickedSlot();
};
This problem does not happen when I set the background of the parent widget to something like green and comment out the setAttribute(Qt::WA_TranslucentBackground); part, this happens only with setAttribute(Qt::WA_TranslucentBackground); part.
How do I fix this?
Platform - OS X Yosemite, Qt 5.3.1, 32 bit.
Ilya's solution below works fine on Windows, but the problem persists on Mac.
Instead of painting/updating manually, just call the setPixmap method, the QLabel should manage itself. The code is working fine, except on Mac OS X:
MyCart.cpp:
#include "MyCart.hpp"
MyCart::MyCart(QWidget *parent): QLabel(parent)
{
resetCartStyle("C:/dev/cart/portrait.png");
}
void MyCart::resetCartStyle(QString url)
{
fPixMap.load(url);
setPixmap(fPixMap);
}
MyCart.hpp:
#pragma once
#include <QLabel>
#include <QPaintEvent>
#include <QPixmap>
class MyCart: public QLabel
{
public:
MyCart(QWidget*);
QPixmap fPixMap;
void resetCartStyle(QString);
};
MyCartParentWidget.cpp:
#include "MyCartParentWidget.hpp"
#include <QPushButton>
MyCartParentWidget::MyCartParentWidget()
{
setFixedSize(800,700);
setWindowFlags(Qt::FramelessWindowHint);
setAttribute(Qt::WA_TranslucentBackground);
fLayout = new QHBoxLayout();
setLayout(fLayout);
fLayout->setContentsMargins(0,0,0,0);
fLayout->setSpacing(0);
fLayout->setMargin(0);
fLayout->setAlignment(Qt::AlignLeft | Qt:: AlignTop);
i = 0;
fCart = new MyCart(this);
fLayout->addWidget(fCart);
QPushButton* p = new QPushButton(this);
p->setText("Toggle");
p->move(0,650);
connect(p,SIGNAL(clicked(bool)),this,SLOT(clickedSlot()));
}
void MyCartParentWidget::clickedSlot()
{
if (i == 0)
{
//enter landscape mode
i = 1;
fCart->resetCartStyle("C:/dev/cart/landscape.png");
}
else
{
//enter portrait mode
i = 0;
fCart->resetCartStyle("C:/dev/cart/portrait.png");
}
}
So what about Mac OS ? The result is a bit better with Qt 5.5.1 than with 5.3.1, here's a screenshot (Mac OS 10.11):
So, there's a ghost of the image remaining. To get to a fully correct display,
the simplest and most effective trick is to hide/show the parent widget before/after toggling:
void MyCartParentWidget::clickedSlot()
{
hide();
if (i == 0)
{
//enter landscape mode
i = 1;
fCart->resetCartStyle("C:/dev/cart/landscape.png");
}
else
{
//enter portrait mode
i = 0;
fCart->resetCartStyle("C:/dev/cart/portrait.png");
}
show();
}
For completeness, below are two other tricks found while searching for a fix, that have fixed the code of the MCV exemple but not the production application.
First trick:
MyCart.cpp
MyCart::MyCart(QWidget *parent): QLabel(parent)
{
// do nothing in the constructor
}
MyCartParentWidget.cpp
MyCartParentWidget::MyCartParentWidget()
{
...previous code
// add this line...
QTimer::singleShot( 0, this, SLOT(onclicked() ); // ...to show the widget
}
This code still doesn't work with Qt 5.3.1, the OP's version.
For this Qt version, another fix is necessary (lifted from this bug report). NB that fix doesn't suppress the ghost image for Qt 5.5.1.
void MyCartParentWidget::paintEvent(QPaintEvent *)
{
QPainter p( this );
p.setCompositionMode( QPainter::CompositionMode_Clear );
p.fillRect( this->rect(), Qt::transparent );
}
So for a working code (for the exemple) on Mac OS with both Qt versions (5.3.1 and 5.5.1), you have to use both tricks.
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.
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