QMainWindow Open File dialog cut off and doesn't respond - c++

My open file dialog in Qt5 is being cut off and it doesn't respond to any mouse clicks. I'm using an OpenGLWindow (per http://doc.qt.io/qt-5/qtgui-openglwindow-example.html) inside the central widget of the QMainWindow (per http://blog.qt.io/blog/2013/02/19/introducing-qwidgetcreatewindowcontainer/). If I don't set the central widget to my OpenGLWindow, then the open file dialog works, but once I use the OpenGLWindow in the central widget, then this problem occurs. See the screenshot below. Any ideas on how to fix this or debug it?
main.cpp:
...
QApplication app(argc, argv);
QSurfaceFormat format;
format.setSamples(16);
MainWindow mainWin;
MyOpenGLWindow window();
window.setFormat(format);
window.setAnimating(true);
QWidget *container = QWidget::createWindowContainer(&window);
mainWin.setCentralWidget(container);
#if defined(Q_OS_SYMBIAN)
mainWin.showMaximized();
#else
mainWin.show();
#endif
....
mainwindow.cpp:
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QFileDialog>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_actionOpen_File_triggered()
{
QString fileName = QFileDialog::getOpenFileName(this, tr("Open File"), "/home");
}
mainwindow.h:
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private:
Ui::MainWindow *ui;
private slots:
void on_actionOpen_File_triggered();
};
#endif // MAINWINDOW_H
mainwindow.ui:
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>800</width>
<height>600</height>
</rect>
</property>
<property name="windowTitle">
<string>MainWindow</string>
</property>
<widget class="QWidget" name="centralwidget"/>
<widget class="QMenuBar" name="menubar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>800</width>
<height>25</height>
</rect>
</property>
<widget class="QMenu" name="menuTest_Window">
<property name="title">
<string>File</string>
</property>
<addaction name="actionOpen_File"/>
</widget>
<addaction name="menuTest_Window"/>
</widget>
<widget class="QStatusBar" name="statusbar"/>
<action name="actionOpen_File">
<property name="text">
<string>Open File</string>
</property>
</action>
</widget>
<resources/>
<connections/>
</ui>

It seems that the way to solve this is to use an QOpenGLWidget (per https://blog.qt.io/blog/2014/09/10/qt-weekly-19-qopenglwidget/). The QWindow approach to using OpenGL doesn't seem to mix well with other QWidgets. I successfully transferred my application to use a QOpenGLWidget now and it works!

Related

Can't get access to QLineEdit

I'm new to QT and I've watched some tutorials about how to create a widget app. In most of them, I had to modify label text using:
ui->label->setText("smthg");
I've tried the same thing with QTextEdit and can't seem have access to it.
Tried ui->help_plz, says "no member named "textEdit" in UI::MainWindow".
How can I access QTextEdit and copy text from it?
Code:
main window.ui:
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>550</width>
<height>368</height>
</rect>
</property>
<property name="windowTitle">
<string>MainWindow</string>
</property>
<widget class="QWidget" name="centralWidget">
<widget class="QPushButton" name="pushButton">
<property name="geometry">
<rect>
<x>140</x>
<y>210</y>
<width>114</width>
<height>32</height>
</rect>
</property>
<property name="text">
<string>PushButton</string>
</property>
</widget>
<widget class="QLabel" name="succ">
<property name="geometry">
<rect>
<x>200</x>
<y>100</y>
<width>59</width>
<height>16</height>
</rect>
</property>
<property name="text">
<string>TextLabel</string>
</property>
</widget>
<widget class="QLineEdit" name="help_plz">
<property name="geometry">
<rect>
<x>230</x>
<y>60</y>
<width>113</width>
<height>21</height>
</rect>
</property>
</widget>
</widget>
<widget class="QMenuBar" name="menuBar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>550</width>
<height>22</height>
</rect>
</property>
</widget>
<widget class="QToolBar" name="mainToolBar">
<attribute name="toolBarArea">
<enum>TopToolBarArea</enum>
</attribute>
<attribute name="toolBarBreak">
<bool>false</bool>
</attribute>
</widget>
<widget class="QStatusBar" name="statusBar"/>
</widget>
<layoutdefault spacing="6" margin="11"/>
<resources/>
<connections/>
</ui>
main.cpp:
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
mainwidow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QTextEdit>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_pushButton_clicked()
{
ui->succ->setText("yeah");
ui->help_plz //no member named "help_plz" in UI::MainWindow
}
main.h:
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = nullptr);
~MainWindow();
private slots:
void on_pushButton_clicked();
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
It says no member named "textEdit" in UI::MainWindow because there isn't anything called textEdit in your .ui file (you can search it yourself to confirm it). You cannot access UI elements that are not there. Add a line edit to your ui file.
QMainWindows can be tricky. You need to set your central widget explicitly:
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
setCentralWidget(ui->centralWidget);
}
void MainWindow::on_pushButton_clicked()
{
ui->succ->setText("yeah");
ui->help_plz->setText("xxx"); //no member named "help_plz" in UI::MainWindow
}
This should compile (though I doubt it does what you want). FWIW: note that this exercise would have been more straightforward had you used QWidget instead of QMainWindow as your UI.

QWidget move() and QGraphicsOpacityEffect causing black border

This took me awhile to figure out... but whenever I try to use a QWidget's move() (or even setGeometry) function that has a child QWidgit with a QGraphicsOpacityEffect assigned to it, it causes the QWidgit to have a black border along the right and bottom sides.
The border is exactly the size of the amount of pixels that I moved. If I increase the amount I move the widget, the border increases also...
If I remove the move() call, the problem is fixed... If I use 0.99 instead of 1.0 in the setOpacity() call, it fixes the problem...
Here's a picture of the issue...
Does anyone know how to avoid/fix this...?
Here's my code.
mainwindow.ui
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>560</width>
<height>351</height>
</rect>
</property>
<property name="windowTitle">
<string>MainWindow</string>
</property>
<widget class="QWidget" name="centralWidget">
<widget class="QWidget" name="TestHolder2" native="true">
<property name="geometry">
<rect>
<x>200</x>
<y>90</y>
<width>120</width>
<height>80</height>
</rect>
</property>
</widget>
</widget>
</widget>
<layoutdefault spacing="6" margin="11"/>
<resources/>
<connections/>
</ui>
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
mainwindow.cpp
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
ui->TestHolder2->resize(450, 250);
ui->TestHolder2->move(11, 11);
ui->TestHolder2->setStyleSheet("background-color: black;");
QWidget* new_widget = new QWidget(ui->TestHolder2);
new_widget->setStyleSheet("background-color:red;");
new_widget->resize(450, 250);
QGraphicsOpacityEffect* opacity_effect = new QGraphicsOpacityEffect(new_widget);
new_widget->setGraphicsEffect(opacity_effect);
opacity_effect->setOpacity(1);
}
MainWindow::~MainWindow()
{
delete ui;
}
main.cpp
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}

QGraphicsView's MousePressEvent is not called

In a recent project, I tried to draw points on a scene after clicking on the corresponding location within GraphicsView, but nothing happend. I tracked the error down to a missing call of ClickableMap::mousePressEvent(const QMouseEvent&).
In this minimal example, nothing is printed after a mouse click on the white Widget, but a message should be printed. I will load an image into the scene, if needed.
What goes wrong here? Many thanks in advance!
ClickableMap.h:
#ifndef CLICKABLEMAP_H
#define CLICKABLEMAP_H
#include <QMouseEvent>
#include <QGraphicsView>
#include <QPoint>
class ClickableMap: public QGraphicsView {
Q_OBJECT
public:
using QGraphicsView::QGraphicsView; // seit C++ 11, benötigt wird mindestens GCC 4.8
// Destruktor entfällt, da argumentlos
void mousePressEvent(const QMouseEvent& event);
signals:
void mousePressed(const QPoint&);
};
#endif // CLICKABLEMAP_H
MainWindow.h:
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QDebug>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private:
Ui::MainWindow *ui;
public slots:
void erster_klick(const QPoint& punkt);
};
#endif // MAINWINDOW_H
ClickableMap.cpp:
#include <QMouseEvent>
#include <QPoint>
#include "ClickableMap.h"
#include <QDebug>
#include <QMessageBox>
void ClickableMap::mousePressEvent(const QMouseEvent& event){
const QPoint& punkt = event.pos();
qDebug() << "Maus gepresst";
QMessageBox::information(this, tr("Dialog"), "Detected click in Drawspace");
emit mousePressed(punkt);
}
main.cpp:
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
mainwindow.cpp:
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
connect(ui->graphicsView, &ClickableMap::mousePressed, this, erster_klick);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::erster_klick(const QPoint& punkt){
qDebug() << "Ich bin nun im Slot";
qDebug() << punkt;
}
mainwindow.ui:
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>300</height>
</rect>
</property>
<property name="windowTitle">
<string>MainWindow</string>
</property>
<widget class="QWidget" name="centralWidget">
<widget class="ClickableMap" name="graphicsView">
<property name="geometry">
<rect>
<x>80</x>
<y>20</y>
<width>256</width>
<height>192</height>
</rect>
</property>
<property name="mouseTracking">
<bool>true</bool>
</property>
</widget>
</widget>
<widget class="QMenuBar" name="menuBar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>26</height>
</rect>
</property>
</widget>
<widget class="QToolBar" name="mainToolBar">
<attribute name="toolBarArea">
<enum>TopToolBarArea</enum>
</attribute>
<attribute name="toolBarBreak">
<bool>false</bool>
</attribute>
</widget>
<widget class="QStatusBar" name="statusBar"/>
</widget>
<layoutdefault spacing="6" margin="11"/>
<customwidgets>
<customwidget>
<class>ClickableMap</class>
<extends>QGraphicsView</extends>
<header>clickablemap.h</header>
</customwidget>
</customwidgets>
<resources/>
<connections/>
</ui>
Testanwendung.pro:
#-------------------------------------------------
#
# Project created by QtCreator 2017-09-18T19:53:12
#
#-------------------------------------------------
QT += core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = Testanwendung
TEMPLATE = app
# The following define makes your compiler emit warnings if you use
# any feature of Qt which has been marked as deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS
# You can also make your code fail to compile if you use deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
SOURCES += \
main.cpp \
mainwindow.cpp \
clickablemap.cpp
HEADERS += \
mainwindow.h \
clickablemap.h
FORMS += \
mainwindow.ui
When overriding parent methods it is necessary to copy the names exactly as they were written to the parent, according to the docs:
void QGraphicsView::mousePressEvent(QMouseEvent *event)
That is to say it receives as a parameter a pointer and not a reference, in your case you must make the following changes:
*.h
void mousePressEvent(QMouseEvent *event);
*.cpp
void ClickableMap::mousePressEvent(QMouseEvent *event){
const QPoint& punkt = event->pos();
qDebug() << "Maus gepresst";
QMessageBox::information(this, tr("Dialog"), "Detected click in Drawspace");
emit mousePressed(punkt);
}
You should also change the following:
connect(ui->graphicsView, &ClickableMap::mousePressed, this, erster_klick);
to:
connect(ui->graphicsView, &ClickableMap::mousePressed, this, &MainWindow::erster_klick);

QByteArray to Double in Qt C++ 5.8.0

I have a serial comport data read write program. Data is being read from the comport 4 (Eg: 1022), but when I'm trying to do a mathematical calculation of the data 1022/2 then its give me output as 0.5 5.0 51.00 511.0 means its not taking the whole 1022 as a single number for the mathematical calculation. Its take 1 first then divide 1/2=0.5 then once 0 digit receive it take as 10/2=5 and so on. But I want 1022 as a single digit number like (eg: 1022/2=511)
I have tried to convert the QByteArray into Double for the calculation.
void MainWindow::readData()
{
QByteArray data = serial->readAll();
bool ok;
QByteArray cata= QByteArray::number(data.toDouble(&ok)/2);
console->putData(cata);
}
So here an example of a TCP client/server in Qt. the server sends 1022.72, and the client receives it and shows the result value divided by 2. (run the server then the client:
Server Code:
test.pro:
#-------------------------------------------------
#
# Project created by QtCreator 2017-06-26T12:49:54
#
#-------------------------------------------------
QT += core gui network
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = test
TEMPLATE = app
# The following define makes your compiler emit warnings if you use
# any feature of Qt which as been marked as deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS
# You can also make your code fail to compile if you use deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
SOURCES += main.cpp\
mainwindow.cpp
HEADERS += mainwindow.h
FORMS += mainwindow.ui
main.cpp:
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
mainwindow.cpp:
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>
#include <QHostAddress>
#include <QAbstractSocket>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow),
_server(this)
{
ui->setupUi(this);
_server.listen(QHostAddress::Any, 4242);
connect(&_server, SIGNAL(newConnection()), this, SLOT(onNewConnection()));
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::onNewConnection()
{
QTcpSocket *clientSocket = _server.nextPendingConnection();
connect(clientSocket, SIGNAL(readyRead()), this, SLOT(onReadyRead()));
connect(clientSocket, SIGNAL(stateChanged(QAbstractSocket::SocketState)), this, SLOT(onSocketStateChanged(QAbstractSocket::SocketState)));
_sockets.push_back(clientSocket);
for (QTcpSocket* socket : _sockets) {
double data = 1022.72;
// socket->write(QByteArray::fromStdString(clientSocket->peerAddress().toString().toStdString() + " connected to server !\n"));
socket->write(QByteArray::fromStdString(QVariant(data).toString().toStdString()));
}
}
void MainWindow::onSocketStateChanged(QAbstractSocket::SocketState socketState)
{
if (socketState == QAbstractSocket::UnconnectedState)
{
QTcpSocket* sender = static_cast<QTcpSocket*>(QObject::sender());
_sockets.removeOne(sender);
}
}
void MainWindow::onReadyRead()
{
QTcpSocket* sender = static_cast<QTcpSocket*>(QObject::sender());
QByteArray datas = sender->readAll();
for (QTcpSocket* socket : _sockets) {
if (socket != sender)
socket->write(QByteArray::fromStdString(sender->peerAddress().toString().toStdString() + ": " + datas.toStdString()));
}
}
mainwindow.h:
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QTcpServer>
#include <QTcpSocket>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
public slots:
void onNewConnection();
void onSocketStateChanged(QAbstractSocket::SocketState socketState);
void onReadyRead();
private:
Ui::MainWindow *ui;
QTcpServer _server;
QList<QTcpSocket*> _sockets;
};
#endif // MAINWINDOW_H
mainwindow.ui: (empty)
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>300</height>
</rect>
</property>
<property name="windowTitle">
<string>MainWindow</string>
</property>
<widget class="QWidget" name="centralWidget">
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<layout class="QVBoxLayout" name="verticalLayout"/>
</item>
</layout>
</widget>
<widget class="QMenuBar" name="menuBar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>25</height>
</rect>
</property>
</widget>
<widget class="QToolBar" name="mainToolBar">
<attribute name="toolBarArea">
<enum>TopToolBarArea</enum>
</attribute>
<attribute name="toolBarBreak">
<bool>false</bool>
</attribute>
</widget>
<widget class="QStatusBar" name="statusBar"/>
</widget>
<layoutdefault spacing="6" margin="11"/>
<resources/>
<connections/>
</ui>
Client code:
test2.pro:
#-------------------------------------------------
#
# Project created by QtCreator 2017-06-26T14:34:11
#
#-------------------------------------------------
QT += core gui network
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = test2
TEMPLATE = app
# The following define makes your compiler emit warnings if you use
# any feature of Qt which as been marked as deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS
# You can also make your code fail to compile if you use deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
SOURCES += main.cpp\
mainwindow.cpp
HEADERS += mainwindow.h
FORMS += mainwindow.ui
main.cpp:
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
mainwindow.cpp:
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>
#include <QHostAddress>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow),
_socket(this)
{
ui->setupUi(this);
_socket.connectToHost(QHostAddress("127.0.0.1"), 4242);
connect(&_socket, SIGNAL(readyRead()), this, SLOT(onReadyRead()));
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::onReadyRead()
{
QByteArray datas = _socket.readAll();
qDebug() << QVariant(datas).toDouble() / 2;
ui->label->setText(QVariant(QVariant(datas).toDouble() / 2).toString());
_socket.write(QByteArray("ok !\n"));
}
mainwindow.h:
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QTcpSocket>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
public slots:
void onReadyRead();
private:
Ui::MainWindow *ui;
QTcpSocket _socket;
};
#endif // MAINWINDOW_H
mainwindow.ui: (result written here and also with qDebug)
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>300</height>
</rect>
</property>
<property name="windowTitle">
<string>MainWindow</string>
</property>
<widget class="QWidget" name="centralWidget">
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QLabel" name="label">
<property name="text">
<string/>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<widget class="QMenuBar" name="menuBar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>25</height>
</rect>
</property>
</widget>
<widget class="QToolBar" name="mainToolBar">
<attribute name="toolBarArea">
<enum>TopToolBarArea</enum>
</attribute>
<attribute name="toolBarBreak">
<bool>false</bool>
</attribute>
</widget>
<widget class="QStatusBar" name="statusBar"/>
</widget>
<layoutdefault spacing="6" margin="11"/>
<resources/>
<connections/>
</ui>

Qt stylesheet in derived class in C++ namespace (selector)

I want to use my global qss stylesheet with a derived class. I understand I have to override the paintEvent (style sheet reference , or here).
void CustomWidget::paintEvent(QPaintEvent *) {
QStyleOption opt;
opt.init(this); // tried initFrom too, same result=>not working
QPainter p(this);
style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this);
}
However, it does not seem to work. With CDerived:QWidget and the following style sheet lines I face:
CDerived { background-color: black; } // no effect
QWidget { background-color: black; } // works
CDerived implements paintEvent as above. Anything else I need to do?
-- Edit / Solution --
Thanks to JK's hint I have figured it out. My above example is actually not correctly reflecting my scenario. My real class resides in a C++ namespace (my mistake I have missed that). So I have to write MyNamespace--CDerived in the qss. See "Widgets inside C++ namespaces"
After I have tried JK's simple example here, I suddenly realized my mistake!
Correct one:
MyNamespace--CDerived { background-color: black; } // works, use -- for ::
Remarks: Relateds SO question (a,b), but with no answer to this particular question. My derived class resides in a C++ namespace.
It is strange....it works fine for me:
untitled.pro:
#-------------------------------------------------
#
# Project created by QtCreator 2014-10-07T11:34:54
#
#-------------------------------------------------
QT += core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = untitled
TEMPLATE = app
SOURCES += main.cpp\
mainwindow.cpp \
mywidget.cpp
HEADERS += mainwindow.h \
mywidget.h
FORMS += mainwindow.ui
mainwindow.h:
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
mainwindow.cpp:
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
}
MainWindow::~MainWindow()
{
delete ui;
}
mainwindow.ui:
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>300</height>
</rect>
</property>
<property name="windowTitle">
<string>MainWindow</string>
</property>
<property name="styleSheet">
<string notr="true"/>
</property>
<widget class="QWidget" name="centralWidget">
<widget class="MyWidget" name="widget" native="true">
<property name="geometry">
<rect>
<x>70</x>
<y>30</y>
<width>201</width>
<height>121</height>
</rect>
</property>
<property name="styleSheet">
<string notr="true"/>
</property>
<widget class="QPushButton" name="pushButton">
<property name="geometry">
<rect>
<x>30</x>
<y>20</y>
<width>75</width>
<height>23</height>
</rect>
</property>
<property name="text">
<string>PushButton</string>
</property>
</widget>
</widget>
</widget>
<widget class="QMenuBar" name="menuBar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>21</height>
</rect>
</property>
</widget>
<widget class="QToolBar" name="mainToolBar">
<attribute name="toolBarArea">
<enum>TopToolBarArea</enum>
</attribute>
<attribute name="toolBarBreak">
<bool>false</bool>
</attribute>
</widget>
<widget class="QStatusBar" name="statusBar"/>
</widget>
<layoutdefault spacing="6" margin="11"/>
<customwidgets>
<customwidget>
<class>MyWidget</class>
<extends>QWidget</extends>
<header>mywidget.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<resources/>
<connections/>
</ui>
mywidget.h:
#ifndef MYWIDGET_H
#define MYWIDGET_H
#include <QWidget>
class MyWidget : public QWidget
{
Q_OBJECT
public:
explicit MyWidget(QWidget *parent = 0);
protected:
void paintEvent(QPaintEvent *e);
};
#endif // MYWIDGET_H
mywidget.cpp:
#include "mywidget.h"
#include <QStyleOption>
#include <QPainter>
MyWidget::MyWidget(QWidget *parent) :
QWidget(parent)
{
}
void MyWidget::paintEvent(QPaintEvent *e)
{
Q_UNUSED(e)
QStyleOption opt;
opt.init(this); // tried initFrom too, same result=>not working
QPainter p(this);
style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this);
}
main.cpp:
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
a.setStyleSheet("MyWidget { background-color: red; }");
MainWindow w;
w.show();
return a.exec();
}