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();
}
Related
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.
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);
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>
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!
How is it possible to move a QGraphicsscene inside a View?
I have a Scene filling the entire View. The Scene is containing one (will be more later) Item (QImage for now), which is updated every few seconds.
My goal is to move the content of the item with mouseMoveEvent. While the item is beeing updated (lasts a few seconds) i want to move the whole Scene and reset the movement after the item is fully updated.
For now I tried overriding the mouseMoveEvent of QGraphicsScene and emit a signal to PPI-Class containintg the QGraphicsScene Objet. The onMouseMoveEvent-slot then tries to set the sceneRect. But this does not work, I get a StackOverflow-Exception.
How can i get this to work? Thank you!
main.cpp
#include "ppi.h"
#include <QtGui/QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
PPI w;
w.show();
return a.exec();
}
ppi.ui (just added a graphicsview with size of 1024x1024 and name gVPPI to the mainwindow)
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>PPIClass</class>
<widget class="QMainWindow" name="PPIClass">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>1079</width>
<height>1113</height>
</rect>
</property>
<property name="windowTitle">
<string>PPI</string>
</property>
<widget class="QWidget" name="centralWidget">
<widget class="QGraphicsView" name="gVPPI">
<property name="geometry">
<rect>
<x>10</x>
<y>10</y>
<width>1024</width>
<height>1024</height>
</rect>
</property>
</widget>
</widget>
<widget class="QMenuBar" name="menuBar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>1079</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"/>
<resources>
<include location="ppi.qrc"/>
</resources>
<connections/>
</ui>
ppi.h
#ifndef PPI_H
#define PPI_H
#include <QtGui/QMainWindow>
#include "ui_ppi.h"
#include "ppiscene.h"
#include <QGraphicsView>
#include <QGraphicsPixmapItem>
#include <QDebug>
class PPI : public QMainWindow
{
Q_OBJECT
public:
PPI(QWidget *parent = 0, Qt::WFlags flags = 0);
~PPI();
private:
Ui::PPIClass ui;
PPIScene* ppiScene;
QGraphicsPixmapItem *videoPixmap;
QImage newImage();
bool moveReset;
QPointF moveCoordinates;
QPointF startMoveCoordinates;
protected slots:
void onMouseMoved(QPointF coordinates, QGraphicsSceneMouseEvent *event);
};
#endif // PPI_H
ppi.cpp
#include "ppi.h"
PPI::PPI(QWidget *parent, Qt::WFlags flags)
: QMainWindow(parent, flags)
{
ui.setupUi(this);
ppiScene = new PPIScene(this);
ppiScene->setSceneRect(0,0,1024,1024);
ui.gVPPI->setScene(ppiScene);
ui.gVPPI->setMouseTracking(true);
videoPixmap = ppiScene->addPixmap(QPixmap::fromImage(newImage()));
startMoveCoordinates = QPointF(0,0);
connect(ppiScene, SIGNAL(mouseMoved(QPointF, QGraphicsSceneMouseEvent*)), this, SLOT(onMouseMoved(QPointF, QGraphicsSceneMouseEvent*)));
}
PPI::~PPI()
{
}
void PPI::onMouseMoved(QPointF coordinates, QGraphicsSceneMouseEvent *event)
{
//move view
if(event->modifiers() & Qt::ControlModifier)
{
moveCoordinates = coordinates;
//ui.gVPPI->translate(moveCoordinates.x() - startMoveCoordinates.x(), moveCoordinates.y() - startMoveCoordinates.y());
ppiScene->setSceneRect(moveCoordinates.x() - startMoveCoordinates.x(), moveCoordinates.y() - startMoveCoordinates.y(), 1024, 1024);
qDebug() << coordinates;
qDebug() << "dx" << moveCoordinates.x() - startMoveCoordinates.x();
qDebug() << "dy" << moveCoordinates.y() - startMoveCoordinates.y();
qDebug() << "";
}
}
QImage PPI::newImage() {
QImage image = QImage(1024, 1024, QImage::Format_Indexed8);
image.setColorCount(256);
for (int i = 0; i < 256; ++i)
image.setColor(i, qRgb(i, 0, 0));
image.fill(200);
return image;
}
ppiscene.h
#ifndef PPISCENE_H
#define PPISCENE_H
#include <QGraphicsScene>
#include <QGraphicsSceneMouseEvent>
class PPIScene : public QGraphicsScene
{
Q_OBJECT
public:
PPIScene(QObject *parent);
~PPIScene();
QPointF mouseCoordinates;
private:
protected:
void mouseMoveEvent(QGraphicsSceneMouseEvent *event);
signals:
void mouseMoved(QPointF coordinates, QGraphicsSceneMouseEvent *event);
};
#endif // PPISCENE_H
ppiscene.cpp
#include "ppiscene.h"
PPIScene::PPIScene(QObject *parent)
: QGraphicsScene(parent)
{
}
PPIScene::~PPIScene()
{
}
void PPIScene::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
{
mouseCoordinates = event->scenePos();
emit mouseMoved(mouseCoordinates, event);
QGraphicsScene::mouseMoveEvent(event);
}