Qt-opengl-debug-SIGSEGV-how to fix? - c++

I follow tutorial on this: https://www.youtube.com/watch?v=1nzHSkY4K18
1/test_opengl.pro
==============================================
QT += core gui opengl
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = test_opengl
TEMPLATE = app
SOURCES += main.cpp\
mainwindow.cpp \
glwidget.cpp
HEADERS += mainwindow.h \
glwidget.h
FORMS += mainwindow.ui
================================================
2/glwidget.h
================================================
#ifndef GLWIDGET_H
#define GLWIDGET_H
#include <QGLWidget>
class GLWidget : public QGLWidget
{
Q_OBJECT
public:
explicit GLWidget(QWidget *parent = 0);
void initializeGL();
void paintGL();
void resizeGL(int w, int h);
};
#endif // GLWIDGET_H
============================================================
3/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
============================================================
4/glwidget.cpp
============================================================
#include "glwidget.h"
GLWidget::GLWidget(QWidget *parent) :
QGLWidget(parent)
{
}
void GLWidget::initializeGL()
{
}
void GLWidget::paintGL()
{
}
void GLWidget::resizeGL(int w, int h)
{
}
============================================================
5/main.cpp
============================================================
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
============================================================
6/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;
}
============================================================
7/mainwindow.ui
============================================================
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<property name="windowModality">
<enum>Qt::ApplicationModal</enum>
</property>
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>555</width>
<height>365</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="windowTitle">
<string>Opengl</string>
</property>
<widget class="QWidget" name="centralWidget">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="GLWidget" name="widget" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="pushButton">
<property name="text">
<string>&Quit</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</widget>
<layoutdefault spacing="6" margin="11"/>
<customwidgets>
<customwidget>
<class>GLWidget</class>
<extends>QWidget</extends>
<header>glwidget.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<resources/>
<connections>
<connection>
<sender>pushButton</sender>
<signal>clicked()</signal>
<receiver>MainWindow</receiver>
<slot>close()</slot>
<hints>
<hint type="sourcelabel">
<x>383</x>
<y>342</y>
</hint>
<hint type="destinationlabel">
<x>390</x>
<y>230</y>
</hint>
</hints>
</connection>
</connections>
</ui>
============================================================
When debugging, i got :
The inferior stopped because it received a signal from the Operating System.
Signal name : SIGSEGV
Signal meaning : Segmentation fault
and this on Disassembler ??
0x143d1fa6 ----------- 83 80 40 01 00 00 ff-------------addl ----- $0xffffffff,0x140(%eax)
Something wrong about "access memory illegally", "uninitialized pointers" ? How can i fix it ?
I use Qt5.3.2,mingw, window 7 32bit. My screen: http://postimg.org/image/pspg5e0g7/

I think something wrong with my driver, i try to remove and set up Qt but older version (Qt 4.8.6) and it's run.

Related

Changing dialog's parent disables drag and drop

I have a main window and a dialog that is opened from this window on a button click. For performance reasons, there is a dialog cache, that keeps an instance of the dialog and only shows it when the dialog should be opened instead of creating new instance. In the dialog, there's a QListWidget with some items which order can be changed by drag and drop. This works when I first open the dialog, but when I close it and open it again, I'm unable to drop the items, I get a Qt::ForbiddenCursor.
The issue seems to be caused by calling setParent(nullptr) when closing the dialog (or likely by just changing the parent). If I remove this line, drag and drop works. However I need this to prevent the dialog from being deleted by the parent and also the dialog can have different parents in different contexts (this isn't obvious from my simplified example). Any idea what is wrong with this approach? My Qt version is 5.9.3. Can this be a Qt bug?
MainWindow.h:
#include "ui_mainwindow.h"
#include "dialog.h"
#include <QPushButton>
#include <QMainWindow>
#include <memory>
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget* parent = nullptr) : QMainWindow(parent), ui(new Ui::MainWindow)
{
ui->setupUi(this);
dialog.reset(new Dialog(this));
dialog->setAttribute(Qt::WA_DeleteOnClose, false);
connect(ui->button, &QPushButton::pressed, [&]
{
dialog->setParent(this, dialog->windowFlags());
dialog->open();
});
}
~MainWindow()
{
delete ui;
}
private:
Ui::MainWindow* ui;
std::unique_ptr<Dialog> dialog;
};
Dialog.h:
#include "ui_dialog.h"
#include <QDialog>
class Dialog : public QDialog
{
Q_OBJECT
public:
explicit Dialog(QWidget* parent) : QDialog(parent), ui(new Ui::Dialog)
{
ui->setupUi(this);
ui->listWidget->addItem("first");
ui->listWidget->addItem("second");
ui->listWidget->addItem("third");
}
~Dialog()
{
delete ui;
}
public slots:
virtual void reject() override
{
setParent(nullptr);
QDialog::reject();
}
private:
Ui::Dialog* ui;
};
Dialog.ui - simple dialog with QListWidget and reject button
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Dialog</class>
<widget class="QDialog" name="Dialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>548</width>
<height>397</height>
</rect>
</property>
<property name="windowTitle">
<string>Dialog</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QListWidget" name="listWidget">
<property name="dragDropMode">
<enum>QAbstractItemView::DragDrop</enum>
</property>
<property name="defaultDropAction">
<enum>Qt::MoveAction</enum>
</property>
</widget>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Close</set>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>Dialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>248</x>
<y>254</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>Dialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>
MainWindow.ui - default main window with one button
<?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>432</width>
<height>316</height>
</rect>
</property>
<property name="windowTitle">
<string>MainWindow</string>
</property>
<widget class="QWidget" name="centralWidget">
<widget class="QPushButton" name="button">
<property name="geometry">
<rect>
<x>40</x>
<y>30</y>
<width>80</width>
<height>21</height>
</rect>
</property>
<property name="text">
<string>PushButton</string>
</property>
</widget>
</widget>
<widget class="QMenuBar" name="menuBar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>432</width>
<height>20</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();
}
The below reproduces the issue. It is indeed a Qt bug. OP reported the bug: https://bugreports.qt.io/browse/QTBUG-70240
The problem is because QWidget recreates the drop site while the Qt::Window flag is off, invoking QWindowsWindow::updateDropSite, which does the wrong thing and calls setDropSiteEnabled(false).
The two equivalent workarounds are:
dialog->setParent(newParent) is replaced by:
auto flags = dialog->windowFlags();
dialog->setParent(newParent, {});
dialog->setWindowFlags(flags);
dialog->setParent(nullptr) is replaced by:
dialog->setParent(nullptr, dialog->windowFlags());
The first workaround undoes the damaged state of the widget. The second workaround doesn't, i.e. needs to be always used, or else the first workaround has to be invoked once to restore the usable drop target state.
// https://github.com/KubaO/stackoverflown/tree/master/questions/dialog-parent-dnd-52061919
#include <QtWidgets>
int main(int argc, char *argv[]) {
QApplication app(argc, argv);
QWidget ui;
QVBoxLayout layout{&ui};
QPushButton button{"Toggle List"};
QCheckBox workaround1{"Workaround 1"};
QCheckBox workaround2{"Workaround 2"};
for (auto w : QWidgetList{&button, &workaround1, &workaround2}) layout.addWidget(w);
workaround2.setChecked(true);
QListWidget listWidget;
Q_ASSERT(!listWidget.testAttribute(Qt::WA_DeleteOnClose));
listWidget.setWindowFlags(Qt::Window | Qt::FramelessWindowHint);
listWidget.setDragDropMode(QAbstractItemView::DragDrop);
listWidget.setDefaultDropAction(Qt::MoveAction);
for (auto s : QStringList{"first", "second", "third"}) listWidget.addItem(s);
QObject::connect(&button, &QPushButton::pressed, [&] {
if (!listWidget.parent()) {
if (!workaround1.isChecked())
listWidget.setParent(&button, listWidget.windowFlags());
else {
auto flags = listWidget.windowFlags();
listWidget.setParent(&button, {});
listWidget.setWindowFlags(flags);
}
listWidget.show();
} else {
if (!workaround2.isChecked())
listWidget.setParent(nullptr);
else
listWidget.setParent(nullptr, listWidget.windowFlags());
listWidget.close();
}
});
ui.setMinimumSize(320, 200);
ui.show();
return app.exec();
}

How do I fully clear a QTreeWidget selection?

I'm trying to make a program that has multiple QTreeWidget's. However, my goal is to ONLY allow for 1 QTreeWidget row to be selected at a time.
I've kind of managed to make this happen using the currentItemChanged signal, but it bugs out.
To reproduce the issue...
Select a row on one QTreeWidget.
Select another row on the OTHER QTreeWidget. At this point all QTreeWidget selection are removed (great that's exactly what I wanted).
Select the same row on the same QTreeWidget as step 1. At this point it has now bugged out because your previous selection is still chosen...
Am I clearing the selection improperly, and if so how should I be clearing it?
Here's a picture of the issue.
Here is my source...
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QTreeWidget>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private slots:
void OnSelectedTreeValueChanged(QTreeWidgetItem *current, QTreeWidgetItem *previous);
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>
#include <QTreeWidget>
#include <QTreeWidgetItem>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
ui->treeWidget->expandAll();
ui->treeWidget->setItemsExpandable(false);
ui->treeWidget_2->expandAll();
ui->treeWidget_2->setItemsExpandable(false);
connect(ui->treeWidget, SIGNAL(currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*)), this, SLOT(OnSelectedTreeValueChanged(QTreeWidgetItem*,QTreeWidgetItem*)));
connect(ui->treeWidget_2, SIGNAL(currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*)), this, SLOT(OnSelectedTreeValueChanged(QTreeWidgetItem*,QTreeWidgetItem*)));
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::OnSelectedTreeValueChanged(QTreeWidgetItem *current, QTreeWidgetItem *previous)
{
if(current->childCount() == 0)
{
// Get OUR parrent item.
QTreeWidgetItem* parent_item = current->parent();
// Go through each tree & deselect selections.
QObject* sender_object = sender();
QTreeView* sender_tree = static_cast<QTreeView*>(sender_object);
const QList<QTreeWidget*> children = ui->TreeScrollAreaContents->findChildren<QTreeWidget*>(QRegularExpression(), Qt::FindDirectChildrenOnly);
for(QList<QTreeWidget*>::const_iterator it = children.begin(); it != children.end(); it++)
{
QTreeWidget* child_tree = *it;
if(sender_tree != child_tree)
{
child_tree->clearSelection();
child_tree->clearFocus();
}
}
}
}
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>176</height>
</rect>
</property>
<property name="windowTitle">
<string>MainWindow</string>
</property>
<widget class="QWidget" name="centralWidget">
<widget class="QScrollArea" name="TreeScrollArea">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>401</width>
<height>171</height>
</rect>
</property>
<property name="widgetResizable">
<bool>true</bool>
</property>
<widget class="QWidget" name="TreeScrollAreaContents">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>399</width>
<height>169</height>
</rect>
</property>
<property name="styleSheet">
<string notr="true">#TreeScrollAreaContents {
background-color: #000000;
}</string>
</property>
<layout class="QGridLayout" name="TreeScrollAreaGridLayout">
<property name="leftMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<item row="0" column="0">
<widget class="QTreeWidget" name="treeWidget">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="sizeAdjustPolicy">
<enum>QAbstractScrollArea::AdjustToContents</enum>
</property>
<column>
<property name="text">
<string>1</string>
</property>
</column>
<item>
<property name="text">
<string>Item 1</string>
</property>
<item>
<property name="text">
<string>Sub Item 1</string>
</property>
</item>
<item>
<property name="text">
<string>Sub Item 2</string>
</property>
</item>
<item>
<property name="text">
<string>Sub Item 3</string>
</property>
</item>
<item>
<property name="text">
<string>Sub Item 4</string>
</property>
</item>
</item>
</widget>
</item>
<item row="0" column="1">
<widget class="QTreeWidget" name="treeWidget_2">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="sizeAdjustPolicy">
<enum>QAbstractScrollArea::AdjustToContents</enum>
</property>
<column>
<property name="text">
<string>1</string>
</property>
</column>
<item>
<property name="text">
<string>Item 1</string>
</property>
<item>
<property name="text">
<string>Sub Item 1</string>
</property>
</item>
<item>
<property name="text">
<string>Sub Item 2</string>
</property>
</item>
<item>
<property name="text">
<string>Sub Item 3</string>
</property>
</item>
<item>
<property name="text">
<string>Sub Item 4</string>
</property>
</item>
</item>
</widget>
</item>
</layout>
</widget>
</widget>
</widget>
</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();
}
One thing is the currentItem and another is the selected items, instead of using the currentItemChanged signal you must use the signal itemSelectionChanged. When using clearSelection() the respective QTreeWidget will also emit the signal itemSelectionChanged and this could generate an infinite loop, the solution is to use blockSignals().
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QTreeWidgetItem>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private:
Ui::MainWindow *ui;
private slots:
void OnSelectedTreeValueChanged(); // remove arguments
};
#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QTreeWidget>
#include <QTreeWidgetItem>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
const QList<QTreeWidget*> childrens = ui->TreeScrollAreaContents->findChildren<QTreeWidget*>(QRegularExpression(), Qt::FindDirectChildrenOnly);
for(QTreeWidget* child_tree: childrens)
{
child_tree->expandAll();
child_tree->setItemsExpandable(false);
connect(child_tree, &QTreeWidget::itemSelectionChanged, this, &MainWindow::OnSelectedTreeValueChanged);
}
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::OnSelectedTreeValueChanged()
{
QTreeWidget *sender_tree = qobject_cast<QTreeWidget *>(sender());
if(sender_tree->currentItem()->childCount() == 0)
{
const QList<QTreeWidget*> childrens = ui->TreeScrollAreaContents->findChildren<QTreeWidget*>(QRegularExpression(), Qt::FindDirectChildrenOnly);
for(QTreeWidget* child_tree: childrens)
{
if(sender_tree != child_tree)
{
child_tree->blockSignals(true);
child_tree->clearSelection();
child_tree->blockSignals(false);
}
}
}
}
Note:
I will explain why your method does not work, you are using the currentItem as a basic element of your algorithm, but a currentItem may be selected or no, clearSelection does not affect the currentItem.

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>

QMainWindow Open File dialog cut off and doesn't respond

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!

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();
}