Qt window bugs with OpenGL - c++

I have created a Qt interface to visualise a 3D model (point cloud) and an image. The issue is that when I switch to full screen, (using keystroke F1 for example), I do get my fullscreen mode as expected. But When I switch to normal mode, the 3D model disappears in the widget as shown in the bottom figure.
QGLWidget is inserted like this in QMainWindow:
QMainWindow : setCentralWidget(viewerWidget);
Our 3D Engine Class,OpenGLViewer inherits QGLWidget
the function for toggle full window goes like this:
void OpenGLViewer::toggleFullWindow()
{
if (isFullScreen()) {
setWindowFlags(Qt::Widget);
showNormal();
}
else {
setWindowFlags(Qt::Window);
showFullScreen();
}
}
My ui widget goes like this
QLabel* App::createViewerBox()
{
viewerWidget = dynamic_cast<QWidget*>(viewer);
QHBoxLayout *layoutHor = new QHBoxLayout();
QLabel *frame = new QLabel();
layoutHor->addWidget(viewerWidget,Qt::AlignJustify);
frame->setLayout(layoutHor);
return frame;
}

Related

Why is QSlider not updating it's position immediately in its UI?

I am creating a video application.
Upon starting this app, you would see a VideoWidget looping a playlist along with other widgets in the screen. By clicking the VideoWidget, the VideoWidget will go to fullscreen mode and a volume slider will be laid over it. It would go to show normal if clicked again in fullscreen mode.
To do this I created 2 classes. First, I created a main class that would contain all widgets including the Video widget. Second, I created a custom VideoWidget class. I instatiated my Qslider in this VideoWidget class and I instantiated a VideoWidget Object in my main class whose object is instantiated in main.cpp.
I got what I expect it to do. Except that the slider would not update its position immediately. It would only update position if you click to show normal then click to go back fullscreen. The volume change but the position of slider in UI does not change while in fullscreen.
I would like to ask what am I doing wrong? What should I do so that the slider position would update in UI?
Code Snippet:
in VideoWidget.h
class VideoWidget : public QVideoWidget
{
Q_OBJECT
QVideoWidget* videoWidget;
QMediaPlaylist* playlist;
QMediaPlayer *player;
public:
VideoWidget();
QSlider* slider;
};
In VideoWidget.cpp
VideoWidget::VideoWidget()
: videoWidget(new QVideoWidget(this)),
slider(new QSlider(Qt::Horizontal, this))
{
/*QMediaplaylist *playlist, QMediaPlayer *player instantiated here*/
slider->hide();
slider->setGeometry(300,735,600,20);
slider->setRange(0, 100);
slider->setValue(player->volume());
connect(slider, &QSlider::valueChanged, player, &QMediaPlayer::setVolume);
}
void VideoWidget::changeEvent(QEvent *event)
{
if(event->type() == QEvent::WindowStateChange)
slider->setVisible(windowState() == Qt::WindowFullScreen);
QWidget::changeEvent(event);
}
enter code here
void VideoWidget::resizeEvent(QResizeEvent* event) {
videoWidget->resize(size());
event->accept();
}
void VideoWidget::mousePressEvent(QMouseEvent *event)
{
this->setFullScreen(!isFullScreen());
event->accept();
}
In the MainWidget.cpp
mainwidget::mainwidget(QWidget *parent)
: QWidget(parent)
{
videoWidget = new VideoWidget(); // the video container
videoWidget->setFixedSize(500, 300);
QBoxLayout *displayLayout = new QHBoxLayout;
displayLayout->addWidget(videoWidget, 2);
QBoxLayout *layout = new QVBoxLayout;
layout->addLayout(displayLayout);
setLayout(layout);
videoWidget->setGeometry(100,100,300,400);
videoWidget->show();
}
edit:
This is the app at startup playing a video of my hand.
When I click the Video,
The video sets to fullscreen and the slider appears. The slider can control the volume of mediaplayer but the problem is, it won't move when dragged.
You're very confusing in ways you describe what the problem is, but if I get you right that QSlider doesn't track the mouse but you can change volume with it, presumably with a click?
You had connected valueChangedsignal , which is emitted only after sliderReleased() if tracking property is false. You have to handle Pressed\Moved\Released group of signals if you want to adjust volume continuously, or you can use built-in function of QSlider (which usually is enough):
slider->setTracking(true);

When QDockWidget with QWebEngineView is undocked, other docked widgets don't respond to user action

I have multiple dockwidgets in my main window and everything works fine until I add a dockedwidget with QwebEngineView as the widget.
When a dockwidget with QwebEngineView as a child is undocked, user inputs such as scroll bars in the other docked widgets are ignored. When the dockwidget with QWebEngineView is docked, it works fine.
The code I am testing with is the example project in
..\Qt 5.6\widgets\mainwindows\dockwidgets
with minor modification to add one more dockedwidget with QWebEngineView (see below).
///// added this in void MainWindow::createDockWindows()
WebView* w_view = new WebView(nullptr);
dock = new QDockWidget(tr("WebView"), this);
dock->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea);
dock->setWidget(w_view);
addDockWidget(Qt::LeftDockWidgetArea, dock);
viewMenu->addAction(dock->toggleViewAction());
/// the widget with QWebEngineView
class WebView : public QWidget {
Q_OBJECT
public:
WebView(QWidget* parent = 0)
:QWidget(parent)
{
setObjectName("WebView");
m_webEngineView = new QWebEngineView(this);
m_webEngineView->load(QUrl("http://qt-project.org/"));
}
~WebView() {}
private:
QWebEngineView* m_webEngineView;
};
///////////////////////////
Any help?

QVideoWidget is new window after leaving fullscreen

I want my video player to show the QVideoWidget fullscreen when double clicking. I have created a new class, inherited the QVideoWidget class and I then overwritten the mousDoubleClickEvent.
//Mouse event in new VideoWidget Class
void VideoWidget::mouseDoubleClickEvent(QMouseEvent *event)
{
if( isFullScreen() )
showNormal();
else
setFullScreen( true ); //Show in fullscreen
}
The VideoWidget is used in my main window where (later) all other widgets are placed.
void MainWindow::setupUi()
{
QWidget* centralWidget = new QWidget( this );
QHBoxLayout* centralLayout = new QHBoxLayout( centralWidget );
videoWidget = new VideoWidget( this );
setCentralWidget( centralWidget );
centralLayout->addWidget( videoWidget );
}
The problem is now that whenver I enter the full screen mode by double click and exit again by double click, the video widget is no longer in the MainWindow. It is a new window. How do I place it back to its old position again?
Edit:
The videoWidget seems to be in a new window AND in my centralLayout. But when I close the new window it disappears in my centralLayout too.
I think video widget is being detached from main window when toggling fullscreen. Maybe you should try to re-add it to layout manually after returning to normal mode.

Weird control boundaries detection on QGraphicsProxyWidget

Hello in my application i'm making a QGraphicsView and set the scene on it:
QGraphicsProxyWidget *rotateItemIcon;
HoverFilter *hv = new HoverFilter(); // my hover filter class
connect(hv,SIGNAL(SignalHover(QObject*)),this,SLOT(ObjectHover(QObject*)));
connect(hv,SIGNAL(SignalHoverLeave(QObject*)),this,SLOT(ObjectHoverLeave(QObject*)));
ui->TestIcon->installEventFilter(hv);
...
scene = new QGraphicsScene(this);
scene->setSceneRect(0, 0, 661, 255);
ui->TestIcon->setParent(NULL);
rotateItemIcon = scene->addWidget(ui->TestIcon); // here i add my control to the scene and receive QGraphicsProxyWidget object
rotateItemIcon->setTransformOriginPoint(ui->TestIcon->width()/2,
ui->TestIcon->height()/2);
ui->graphicsViewFive->setScene(scene); //QGraphicsView on my form
ui->graphicsViewFive->show();
my HoverFilter.cpp
#include "hoverfilter.h"
#include "QDebug"
HoverFilter::HoverFilter()
{
}
bool HoverFilter::eventFilter( QObject *dist, QEvent *event )
{
if( event->type() == QEvent::Enter )
{
emit SignalHover(dist);
return true;
}
if( event->type() == QEvent::Leave )
{
emit SignalHoverLeave(dist);
return true;
}
return false;
}
rotateItemIcon is my QGraphicsProxyWidget and the problem is that it has weird boundaries, i need to implement some animation on hover of my control TestIcon, (i done that using event filter) mouse enter and mouse leave fires when i drag my mouse on a random places, not only on my TestIcon control. If do not add my control to the QGraphicsScene hover detection works fine, so i assume this is a scene/proxywidget problem. Is there a way i can set size or boundaries to QGraphicsProxyWidget to stop that?
I'm not sure if I completely understand your question, but it sounds like you're have a widget placed in a scene via a QGraphicsProxyWidget and when you try to detect if your mouse is over the widget you want it to animate.
By 'weird boundaries' I assume you mean the extents to which the proxy widget is accepting the mouse as being over the widget. If so, I suggest either calling setGeometry on the QGraphicsProxyWidget to set its position and dimensions, or inherit from QGraphicsProxyWidget and implement the boundingRect function to define the area of the proxy widget.

QGraphicsView possible bug?

The example code is from my project. I've tried to make it as short as possible and to the point.
The overlay is used to draw over all the other widgets in the app. This works for most widgets, but today I've started to notice that QAbstractScrollArea subclasses are giving me a hard time. The problem is that the overlay appears not on top, and whatever drawing that happens is blocked.
#include <QtGui/QApplication>
#include <QtGui/QVBoxLayout>
#include <QtGui/QGraphicsView>
#include <QtGui/QPushButton>
class View : public QGraphicsView{
public:
View(){
//delete viewport(); setViewport(new QWidget);
}
};
class Widget : public QWidget{
QWidget* overlay_;
public:
Widget(){
resize(512, 512);
QVBoxLayout* layout = new QVBoxLayout;
QPushButton* button = new QPushButton(" Click Me! ");
layout->addWidget(button);
layout->addWidget(new View);
overlay_ = new QWidget(this);
overlay_->installEventFilter(this);
connect(button, SIGNAL(clicked()),
overlay_, SLOT(show()));
overlay_->hide();
setLayout(layout);
}
bool eventFilter(QObject* target, QEvent* event){
if(target == overlay_){
if(event->type() == QEvent::Paint && overlay_->isVisible()){
overlay_->resize(size());
QPainter painter(overlay_);
painter.setPen(QPen(QColor(1, 102, 192, 255), 1, Qt::SolidLine,
Qt::FlatCap, Qt::MiterJoin));
painter.drawRect(rect().adjusted(60, 0, -60, 0));
return true;
}
}
}
};
int main(int argc, char *argv[]){
QApplication a(argc, argv);
Widget w;
w.show();
return a.exec();
}
To fix this in this example and have overlay go on top of View, you'll need to uncomment the commented line at the top. So my question is this: why do I need to delete and assign a new viewport widget in the constructor in order for overlay not get overdrawn?
This isn't a bug with QGraphicsView, it will happen if you use a standard QScrollArea as well.
The issue, I think, is the order in which Qt draws child widgets. Sibling widgets are drawn in the order they are added to the parent (although you can't rely on this).
The reason that resetting the viewport "solved" the problem is because when you do that you create a new QWidget that has no background to be the viewport. The QGraphicsView is still being drawn over the overlay_, it just has a transparent viewport. Notice how it's still drawn behind the pushbutton, however.
If you want to draw an overlay only over the QGraphicsView, you can override QGraphicsView::paintEvent() and do it there. If you want to draw the overlay over your entire widget, I would embed your layout inside a second QWidget and then try using QWidget::raise() to force the overlay visually to the top.