I'm playing a bit with Qt Quick and I wanted to create a title bar for my application. So I inherited QQuickPaintedItem, painted a bit on it and wanted to use it as a title bar for my Window. I'm using Qt 5.7. This succeeded but only to a certain extent...I'll explain more after the code; here is how I did it:
main.cpp
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include "mycustomtitlebar.h"
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
qmlRegisterType<MyCustomTitleBar>("my.custom.lib", 1, 0, "MyCustomTitleBar");
QQmlApplicationEngine engine;
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
return app.exec();
}
main.qml
import QtQuick 2.7
import QtQuick.Window 2.2
import my.custom.lib 1.0
Window {
id: wnd
visible: true
width: 640
height: 480
title: qsTr("Hello World")
MyCustomTitleBar {
id: titleBar
anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.right
height: 100
hostWidget: wnd
}
Rectangle {
color: "beige"
anchors.top: titleBar.bottom
anchors.left: parent.left
anchors.right: parent.right
anchors.bottom: parent.bottom
}
}
mycustomtitlebar.h
#ifndef MYCUSTOMTITLEBAR_H
#define MYCUSTOMTITLEBAR_H
#include <QQuickPaintedItem>
#include <QPoint>
class MyCustomTitleBar : public QQuickPaintedItem
{
Q_OBJECT
Q_PROPERTY(QWindow *hostWidget READ hostWidget WRITE setHostWidget)
public:
MyCustomTitleBar(QQuickItem *parent = 0);
protected:
virtual void paint(QPainter *pPainter) Q_DECL_OVERRIDE;
virtual void mousePressEvent(QMouseEvent *pEvent) Q_DECL_OVERRIDE;
virtual void mouseMoveEvent(QMouseEvent *pEvent) Q_DECL_OVERRIDE;
virtual void mouseReleaseEvent(QMouseEvent *pEvent) Q_DECL_OVERRIDE;
private:
QWindow *hostWidget() const;
void setHostWidget(QWindow *pHostWidget);
private:
QWindow *m_pHostWidget;
QPoint m_initialMousePosition;
bool m_leftMouseButtonPressed;
};
#endif // MYCUSTOMTITLEBAR_H
mycustomtitlebar.cpp
#include "mycustomtitlebar.h"
#include <QPainter>
#include <QDragMoveEvent>
#include <QWindow>
MyCustomTitleBar::MyCustomTitleBar(QQuickItem *parent)
: QQuickPaintedItem(parent),
m_leftMouseButtonPressed(false),
m_pHostWidget(Q_NULLPTR)
{
setAcceptedMouseButtons(Qt::AllButtons);
}
void MyCustomTitleBar::paint(QPainter *pPainter)
{
// Dummy drawing...
const QRect myRect(10, 10, width() - 20, height() - 20);
qDebug() << myRect;
pPainter->drawRect(myRect);
}
void MyCustomTitleBar::mousePressEvent(QMouseEvent *pEvent)
{
m_leftMouseButtonPressed = true;
m_initialMousePosition = pEvent->pos();
}
void MyCustomTitleBar::mouseMoveEvent(QMouseEvent *pEvent)
{
if (m_leftMouseButtonPressed) {
if (!m_pHostWidget) {
qDebug() << Q_FUNC_INFO << "Host widget not set. Please set host widget";
return;
}
const QPoint newMousePosition = pEvent->pos() - m_initialMousePosition + m_pHostWidget->position();
m_pHostWidget->setPosition(newMousePosition);
}
QQuickPaintedItem::mouseMoveEvent(pEvent);
}
void MyCustomTitleBar::mouseReleaseEvent(QMouseEvent *pEvent)
{
m_leftMouseButtonPressed = false;
}
QWindow *MyCustomTitleBar::hostWidget() const
{
return m_pHostWidget;
}
void MyCustomTitleBar::setHostWidget(QWindow *pHostWidget)
{
m_pHostWidget = pHostWidget;
}
Now this code works perfectly, I run the application and I am able to click on the title bar and drag, and the whole window moves where I want it to.
But here is the problem: if I change hostWidget: wnd to hostWidget: parent it doesn't work anymore. Can anyone explain why? Because wnd is the parent after all.
P.S.
I also get this very strange error notification from Qt Creator but the code compiles and runs fine:
Why?...
Because titleBar.parent is not wnd, but wnd.contentItem instead. That's why you find its parent is not wnd.
Why wnd.contentItem instead of wnd ?
Generally, any item will become the parent of all subitems it encloses, but it's not the case for Window.
The problem here, is that the type of parent property is Item. Sadly, Window does not inherit from Item. Thus, a Window should contain a real Item to be the parent of all its children. That's what Window.contentItem is used for.
But here is the problem: if I change hostWidget: wnd to hostWidget: parent
it doesn't work anymore. Can anyone explain why? Because wnd is the parent
after all.
Window QML type instantiates QQuickWindow.
QQuickWindow does not inherit from QQuickItem.
Instead it contains a QQuickItem element accessible through its contentItem() function.
parent property refers to a QQuickItem object.
Therefore in your example titleBar.parent refers to an element of wnd rather than wnd itself.
If an attempt is made internally to dynamically cast titleBar.parent to QWindow* before calling MyCustomTitleBar::setHostWidget() it fails because of (2) above (in that case, you should see a corresponding error in the console).
Related
I am trying to create a qml object dynamically in c++ using the object of c++ class. Below is the minimal code for my approach. Upon execution of this code and after clicking, the application is crashing(see the comment in main.qml).
I have pasted the code below and It can be downloaded here.
main.cpp
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>
#include "scene.h"
int main(int argc, char *argv[])
{
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
scene sc(engine);
QQmlContext* context = engine.rootContext();
context->setContextProperty("sc", &sc);
if (engine.rootObjects().isEmpty())
return -1;
return app.exec();
}
scene.h
#ifndef SCENE_H
#define SCENE_H
#include <QObject>
#include <QQmlApplicationEngine>
#include <QQmlComponent>
class scene : public QObject
{
Q_OBJECT
public:
explicit scene(QQmlApplicationEngine& engine, QObject *parent = nullptr);
QQmlApplicationEngine& engine;
public slots:
void create_rect_object();
};
#endif // SCENE_H
scene.cpp
#include "scene.h"
scene::scene(QQmlApplicationEngine &engine, QObject *parent) : engine(this->engine),QObject(parent)
{
}
void scene::create_rect_object()
{
QQmlComponent component(&engine, QUrl::fromLocalFile("myrect.qml"));
QObject *object = component.create();
object->setProperty("width", 200);
object->setProperty("height", 150);
object->setProperty("color", "blue");
}
main.qml
import QtQuick 2.11
import QtQuick.Window 2.11
Window {
visible: true
width: 640
height: 480
title: qsTr("Hello World")
Rectangle{
anchors.fill: parent
color: "red"
MouseArea{
anchors.fill: parent
onClicked: {
console.log("Before click");
sc.create_rect_object(); // application is crashing here
console.log("after click");
}
}
}
}
myrect.qml
import QtQuick 2.0
Rectangle {
id:id_rec
width: 100
height: 100
color: "green"
x:0
y:0
}
Update
The object to be created is not the child of the root of main window but child of one of the item inside the chain of children items of root of mainwindow. The pseudo structure looks like below.
main.qml
Window {
customitem1{
id:id_ci1
}
customitem2{
id:id_ci1
}
}
customitem1.qml
Item {
customitem3{
id:id_ci3
}
customitem3{
id:id_ci4
}
}
[UPDATED]
You have two errors for crashing and one for not showing rectangles
1.Your scene's Constructor member initializer list is falsy which causes the app crash
(TIP : use different naming for members of the class by prefixing them with m_ e.g: m_engine for READABILITY and not get confused)
//Correct WAY
class Something
{
private:
int m_value1;
double m_value2;
char m_value3;
public:
//################# YOUR CASE ###############################
Something(int number) : m_value1(number), m_value2(2.2), m_value3('c') // directly initialize our member variables
{
// No need for assignment here
}
//#############################################################
Something() : m_value1(1), m_value2(2.2), m_value3('c') // directly initialize our member variables
{
// No need for assignment here
}
void print()
{
std::cout << "Something(" << m_value1 << ", " << m_value2 << ", " << m_value3 << ")\n";
}
}
and it should be like this :
scene::scene(QQmlApplicationEngine &engine, QObject *parent) : engine(engine),QObject(parent)
instead of
scene::scene(QQmlApplicationEngine &engine, QObject *parent) : engine(this->engine),QObject(parent)
2.The url of myrect.qml which you get from local file that isn't found at runtime caused the app crash aslo and the one of remedies is to load it from your qrc file
QQmlComponent component(&engine, QUrl("qrc:/myrect.qml"));
3.And you'll notice after clicking you got no rectangles that's because the rectangles getting created doesn't have a parent and by changing your create_rect_object()(In this example the parent is the invisible root of our window contentItem) you'll get some rectangles :)
//A QQuickWindow always has a single invisible root item containing all of its content.
//To add items to this window, reparent the items to the contentItem or to an existing item in the scene.
//http://doc.qt.io/qt-5/qquickwindow.html#contentItem-prop
void scene::create_rect_object()
{
QQmlComponent component(&engine, QUrl("qrc:/myrect.qml"));
QObject *object = component.create();
QQuickItem *item = qobject_cast<QQuickItem*>(object);
// Set the parent of our created qml rect
item->setParentItem((QQuickItem*)((QQuickWindow *) engine.rootObjects()[0])->contentItem());
//Set some random position and color
item->setProperty("color", QColor::fromRgb(QRandomGenerator::global()->generate()));
item->setX(20+qFloor(QRandomGenerator::global()->generateDouble()*20));
item->setY(20+qFloor(QRandomGenerator::global()->generateDouble()*20));
}
Finding QML Objects from C++
For finding objects and using them as parentItem, you have to set the objectName of your qml object
Rectangle {
...
objectName : "rect_1"
...
}
and in C++
QObject* obj = dynamic_cast<QObject*>(engine.rootObjects()[0]).findChild("rect_1");
In order to convert one GUI interface written in C++ with the Qt libraries to QML, I've to find an alternative to QPainterPath in QML. Indeed, for now, a bunch of shapes are drawn in the GUI interface and the C++ code modifies the color of those objects when certain events happen. QPainterPath objects are used to store those shapes.
I would appreciate if you can show me how to draw two rectangle objects in a QML canvas and then how to modify their filled color within the C++ code.
As I said in my comment, one option could be Canvas, it has methods similar to QPainterPath. In the next part I will show an example where the color can be changed from C ++ through a method that generates random colors and are called by a QTimer:
main.cpp
#include <QColor>
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>
#include <QTime>
#include <QTimer>
class ColorProvider: public QObject{
Q_OBJECT
Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY colorChanged)
public:
QColor color() const{
return mColor;
}
void setColor(const QColor &color){
if(color == mColor)
return;
mColor = color;
emit colorChanged(mColor);
}
Q_INVOKABLE void randomColor(){
qsrand((uint)QTime::currentTime().msec());
setColor(QColor(qrand() % 256, qrand() % 256, qrand() % 256));
}
signals:
void colorChanged(const QColor &color);
private:
QColor mColor;
};
#include "main.moc"
int main(int argc, char *argv[])
{
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QGuiApplication app(argc, argv);
ColorProvider obj;
QTimer timer;
QObject::connect(&timer, &QTimer::timeout, &obj, &ColorProvider::randomColor);
timer.start(100);
QQmlApplicationEngine engine;
engine.rootContext()->setContextProperty("colorProvider", &obj);
engine.load(QUrl(QLatin1String("qrc:/main.qml")));
if (engine.rootObjects().isEmpty())
return -1;
return app.exec();
}
main.qml
import QtQuick 2.7
import QtQuick.Controls 2.0
ApplicationWindow {
visible: true
width: 640
height: 480
title: qsTr("Hello World")
Canvas {
id:canvas
anchors.fill: parent
onPaint:{
var ctx = canvas.getContext('2d');
ctx.lineWidth = 4
ctx.fillStyle = "orange"
ctx.strokeStyle = "red"
ctx.fillRect(50, 40, 100, 100)
ctx.stroke()
ctx.fill()
ctx.lineWidth = 10
ctx.fillStyle = colorProvider.color
ctx.fillRect(150, 150, 300, 300)
ctx.stroke()
ctx.fill()
ctx.roundedRect(20, 20, 40, 40, 10, 10)
}
}
Connections {
target: colorProvider
onColorChanged: canvas.requestPaint()
}
}
The complete example can be found in the following link.
I inherited QQuickWindow and created a frame-less window that can be moved by drag. Inside my window I put a Slider element. The problem is that the Slider forwards the events to the parent window and when I try to change the value on the slider, the window moves along. Here's how it behaves:
Is there a possibility to make the slider accept the mouse events and not forward them to the window?
Here's my code:
main.cpp
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QUrl>
#include "mywindow.h"
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
qmlRegisterType<MyWindow>("mycustomlib", 1, 0, "MyWindow");
QQmlApplicationEngine engine;
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
return app.exec();
}
main.qml
import QtQuick 2.7
import QtQuick.Window 2.2
import QtQuick.Controls 1.4
import mycustomlib 1.0
MyWindow {
width: 300
height: 180
visible: true
x: 250
y: 250
color: "beige"
Slider {
anchors.fill: parent
value: 0.5
}
}
mywindow.h
#ifndef MYWINDOW_H
#define MYWINDOW_H
#include <QQuickWindow>
class MyWindow : public QQuickWindow
{
Q_OBJECT
public:
MyWindow(QWindow *pParent = Q_NULLPTR);
protected:
virtual void mouseMoveEvent(QMouseEvent *e) Q_DECL_OVERRIDE;
virtual void mousePressEvent(QMouseEvent *e) Q_DECL_OVERRIDE;
virtual void mouseReleaseEvent(QMouseEvent* e) Q_DECL_OVERRIDE;
private:
bool m_move;
QPoint m_initialMouseClickPos;
};
#endif // MYWINDOW_H
mywindow.cpp
#include "mywindow.h"
#include <QDebug>
#include <QCursor>
MyWindow::MyWindow(QWindow *pParent) :
QQuickWindow(pParent),
m_move(false)
{
setFlags(Qt::FramelessWindowHint);
}
void MyWindow::mouseMoveEvent(QMouseEvent *e)
{
if (m_move) {
const QPoint newMousePosition = e->pos() - m_initialMouseClickPos + position();
setPosition(newMousePosition);
}
QQuickWindow::mouseMoveEvent(e);
}
void MyWindow::mousePressEvent(QMouseEvent *e)
{
if (e->button() == Qt::LeftButton)
{
m_initialMouseClickPos = e->pos();
m_move = true;
}
QQuickWindow::mousePressEvent(e);
}
void MyWindow::mouseReleaseEvent(QMouseEvent *e)
{
if (e->button() == Qt::LeftButton)
{
m_move = false;
}
QQuickWindow::mouseReleaseEvent(e);
}
The problem is that QQuickWindow::mouseXxxEvent() delivers the event to the item it belongs to. You have overridden the event handlers, do your handling first, and then pass on the event to QQuickWindow. Therefore the Slider receives the events right after you have done your custom event handling. Either don't call the base class implementation when you don`t want it to deliver the event to items, or call the base class implementation first and do your custom handling afterwards only if the event was not accepted or so.
void MyWindow::mousePressEvent(QMouseEvent *e)
{
QQuickWindow::mousePressEvent(e);
if (!e->isAccepted() && e->button() == Qt::LeftButton)
{
m_initialMouseClickPos = e->pos();
m_move = true;
}
}
The slider isn't a widget, and it doesn't process events like widgets do :(
To implement drag on a QQuickWindow, you could have a mouse area in Qt Quick, behind the controls, and have it forward drags to a helper object that then drags the window around.
I'm trying to make an app where you can draw with your finger on a canvas.
To achieve this, I'm subclassing QWidget as MFCanvas, registered the class in QML with
qmlRegisterType<>(), implementing the virtual paintEvent(); function, and
drawing on it with a QPainter inside the paintEvent(); function.
The Problem:
Upon construction, the QPainter throws this warning:
QWidget::paintEngine: Should no longer be called
Then, serveral other related warnings are thrown:
QPainter::begin: Paint device returned engine == 0, type: 1
QPainter::setPen: Painter not active
No wonder: the QPainter didn't draw anything...
Also, am i supposed to call paintEvent(); by myself?
Or should it be called every frame by QWidget, and i somehow messed it up?
I searched the web, but all posts i found had either no answer to them, or they where
using something else than QWidget.
My Code:
mfcanvas.cpp:
#include "mfcanvas.h"
#include <QDebug>
#include <QPainter>
#include <QVector2D>
#include <QList>
MFCanvas::MFCanvas(QWidget *parent) : QWidget(parent)
{
paths = new QList<QList<QVector2D>*>();
current = NULL;
QWidget::resize(100, 100);
}
MFCanvas::~MFCanvas()
{
delete paths;
}
void MFCanvas::paintEvent(QPaintEvent *)
{
if(current!=NULL){
if(current->length() > 1){
QPainter painter(this);
painter.setPen(Qt::black);
for(int i = 1; i < current->length(); i++){
painter.drawLine(current->at(i-1).x(), current->at(i-1).y(), current->at(i).x(), current->at(i).y());
}
}
}
}
void MFCanvas::pressed(float x, float y)
{
if(current==NULL){
qDebug() << "null:"<<current;
current = new QList<QVector2D>();
current->append(QVector2D(x, y));
}else{
qDebug() << "current:"<<current;
}
paintEvent(NULL);
}
void MFCanvas::update(float x, float y)
{
current->append(QVector2D(x, y));
}
void MFCanvas::resize(int w, int h)
{
QWidget::resize(w, h);
}
main.cpp:
#include <QApplication>
#include <QQmlApplicationEngine>
#include <QtQml>
#include <QSurfaceFormat>
#include "creator.h"
#include "mfcanvas.h"
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
qmlRegisterType<MFCanvas>("com.cpp.mfcanvas", 1, 0, "MFCanvas");
QQmlApplicationEngine engine;
QQmlComponent *component = new QQmlComponent(&engine);
QObject::connect(&engine, SIGNAL(quit()), QCoreApplication::instance(), SLOT(quit()));
Creator creator(component);
QObject::connect(component, SIGNAL(statusChanged(QQmlComponent::Status)), &creator, SLOT(create(QQmlComponent::Status)));
component->loadUrl(QUrl("qrc:///main.qml"));
int rv;
rv = app.exec();
delete component;
return rv;
}
creator.cpp:
#include "creator.h"
#include <QQuickWindow>
#include <QDebug>
Creator::Creator(QQmlComponent *component)
{
this->component = component;
}
void Creator::create(QQmlComponent::Status status)
{
if(status == QQmlComponent::Ready){
QObject *topLevel = component->create();
QQuickWindow::setDefaultAlphaBuffer(true);
QQuickWindow *window = qobject_cast<QQuickWindow *>(topLevel);
QSurfaceFormat surfaceFormat = window->requestedFormat();
window->setFormat(surfaceFormat);
window->show();
}
}
main.qml: (the important part)
import QtQuick 2.2
import QtQuick.Controls 1.1
import QtQuick.Controls.Styles 1.2
import QtQuick.Layouts 1.1
import QtQuick.Window 2.0
import com.cpp.mfcanvas 1.0
ApplicationWindow {
visible: true
width: 640
height: 480
title: qsTr("MFCanvas")
onSceneGraphInitialized: {
drawMenu.visible = true;
lineWidth.visible = true;
colorMenu.visible = true;
drawMenu.visible = false;
lineWidth.visible = false;
colorMenu.visible = false;
}
Rectangle {
id: main
anchors.fill: parent
property real toolsH: 15
property real iconW: 25
property real menuH: 8
property real menuW: 16
property real dpi: (Screen.logicalPixelDensity == undefined ? 6 : Screen.logicalPixelDensity) * 1.5
property color choosenColor: Qt.hsla(hue.value, saturation.value, luminance.value, 1)
Text {
anchors.centerIn: parent
font.pointSize: 60
text: "MFCanvas"
}
MFCanvas {
id: canvas
Component.onCompleted: {
canvas.resize(main.width, main.height);
}
}
//...
}
}
Tell me if you need any additional information.
Thank you in advance! =)
This is nicely explained here:
https://forum.qt.io/topic/64693
In short: do not try to paint from the input event handler directly,
but overload the paintEvent method in your widget instead and create the
QPainter there. Use the input event exclusively to modify the internal
data model and use QPainter in paintEvent to display it, on the output path.
In your mfcanvas.cpp, void MFCanvas::pressed(float x, float y) function, the line
paintEvent(NULL);
seems to be disturbing. Tried it in a similar code - I get the same error.
Proposed solution: using this->repaint() or this->update() instead of paintEvent(NULL) to repaint a widget seems to be more appropriate.
Possible explanation: looks like paintEvent() shouldn't be called this straightforward (like paintEvent() is called when paint() function is called). As far as I understand from the QPainter doc, the QPainter works together with the QPaintDevice and the QPaintEngine, these three form the basis for painting. The error QWidget::paintEngine: Should no longer be called puts it quite straight. The lines
QPainter::begin: Paint device returned engine == 0, type: 1
QPainter::setPen: Painter not active
probably indicate that there's no QPaintEngine provided by this painter's QPaintDevice (like QPaintDevice::paintEngine). One can assume that this QPaintEngine is generated or otherwise called to existence by the paint device itself, for example, when the paint() function is called on a widget.
I have found a simple solution myself:
Instead of deriving from QWidget, derive from QQuickPaintedItem. QQuickPaintedItem is a class that was made exactly for what i need: Painting on a QML-Element using a QPainter. Here is the Code (Narrowed down to the essential part):
mfcanvas.h:
class MFCanvas : public QQuickPaintedItem
{
Q_OBJECT
public:
explicit MFCanvas(QQuickItem *parent = 0);
~MFCanvas();
protected:
void paint(QPainter *painter);
mfcanvas.cpp:
void MFCanvas::paint(QPainter *painter)
{
painter->translate(-translation.x(), -translation.y());
//...
}
As you can see, a simple paint() function is provided which hands over a pointer to a QPainter, ready to use. =)
I have this little test-case which is supposed to show two widgets, with one overlapping the other completely. The one is translucent so the other widget should shine through it.
For that purpose, I set a style sheet on the one widget using a type-selector Menu (which is its class name). But instead of making the widget opaque by a factor of 200/255, it makes it completely translucent as if the type-selector doesn't apply at all to the menu object, so that I see no shine of blue anymore.
If I instead use the * selector, it works as expected. I tested the value of metaObject()->className(), which correctly reports Menu. Can anyone hint me to the error I have made please? This is a reduced testcase of a real program which shows a much more weird behavior, and I first want to make this reduced testcase work.
#include <QtGui/QApplication>
#include <QtGui/QWidget>
#include <QtGui/QLayout>
#include <QtGui/QVBoxLayout>
#include <QtGui/QLabel>
#include <QtGui/QResizeEvent>
class Menu: public QWidget {
Q_OBJECT
public:
Menu(bool translucent, QWidget *p):QWidget(p) {
if(translucent) {
setStyleSheet("Menu { background-color: rgba(0, 0, 150, 200) }");
}
QLabel *label = new QLabel(
translucent ? "\n\nHello I'm translucent" : "I'm not translucent");
label->setStyleSheet("color: white; font-size: 20pt");
QLayout *mylayout = new QVBoxLayout;
setLayout(mylayout);
mylayout->addWidget(label);
}
};
class MyWindow : public QWidget {
public:
MyWindow() {
Menu *m1 = new Menu(false, this);
Menu *m2 = new Menu(true, this);
m1->lower();
m2->raise();
}
protected:
void resizeEvent(QResizeEvent *event) {
foreach(QWidget *w, findChildren<QWidget*>()) {
w->setGeometry(0, 0, width(), height());
}
}
};
int main(int argc, char **argv) {
QApplication app(argc, argv);
MyWindow w;
w.show();
app.exec();
}
When using stylesheets with QWidget subclasses, you are supposed to override paintEvent this way:
void Menu::paintEvent(QPaintEvent *)
{
QStyleOption opt;
opt.init(this);
QPainter p(this);
style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this);
}
See the stylesheet reference from Qt documentation.