How to resize main window when bottom element's height change
-
Hi
So in short
When bar is hidden, the window should become smaller in height to
cover the unused area? -
@MoaMoaK
it helped a lot to understand :) so +1 for good description.
Well you can easy adjust the height. If you set the widget widget to fixed size it will never change.
There is a few surprises though.
If you move app to other screen with other resolution.
When you restore old height, it might be too much etc.
Also if he changes res etc.I am thinking about VLC. it has such bar.
But its just black when not there. You really want the window to resize? -
@MoaMoaK
it helped a lot to understand :) so +1 for good description.
Well you can easy adjust the height. If you set the widget widget to fixed size it will never change.
There is a few surprises though.
If you move app to other screen with other resolution.
When you restore old height, it might be too much etc.
Also if he changes res etc.I am thinking about VLC. it has such bar.
But its just black when not there. You really want the window to resize?@mrjj
Yep, fixing the widget size doesn't seems the way to go as the user might resize the window by himself (in that case, the video's aspect ratio might change obviously) and I would like the bar to stay hidden. So i would need to resize the widget on window resized event (might work but not convinced it's the best way though)I can't see how to reduce the bar's height without resizing the video, if you don't resize the window. So yes, i really need to resize the window I guess.
-
@mrjj
Yep, fixing the widget size doesn't seems the way to go as the user might resize the window by himself (in that case, the video's aspect ratio might change obviously) and I would like the bar to stay hidden. So i would need to resize the widget on window resized event (might work but not convinced it's the best way though)I can't see how to reduce the bar's height without resizing the video, if you don't resize the window. So yes, i really need to resize the window I guess.
@MoaMoaK said in How to resize main window when bottom element's height change:
resized event
If you resize in resize event, it often leads to recursive crash.
But you can emit a signal and do it a moment later in the slot.
That should work.Just test it. it might not be optimal but could work.
-
I'm replying after a while because I tryed a lot of stuff since, and I don't want to let this topic falling unanswered in the abyss of the forum. The best solution I've came up with so far is using the resize function on both the main window and the control bar.
At the end of the post there is a working code of a fake video displayed with a control bar under it when the mouse hover the "video" for those interested. I've added an eventfilter to resize the "video" every time the main window is resized as this is how work my video (it made thing a bit harder)
This version is working by using setMaximumHeight() on the control bar, it works because when the window is resized either the "video" takes more space or the control bar takes more space, qt choose to expand the bottom one. For more consistency, it's also possible to use setFixedHeight() on the controlBar but you can"t animate it as easily.
main.cpp
#include "mainwindow.hpp" #include <QApplication> int main(int argc, char *argv[]) { QApplication a(argc, argv); MainWindow w; w.show(); return a.exec(); }
mainwindow.hpp
#ifndef MAINWINDOW_HPP #define MAINWINDOW_HPP #include <QMainWindow> #include <QtQml> #include <QtQuickWidgets/QQuickWidget> #include <QHBoxLayout> #include <QLabel> #include <QTimer> class MainWindow : public QMainWindow { Q_OBJECT public: MainWindow(QWidget *parent = 0); bool eventFilter(QObject *obj, QEvent *event); ~MainWindow(); private: QPixmap *fakecontent; // An image that acts as the video QLabel *video; // The QWidget containing the "video" QQuickWidget *controlbar; // The control bar in QML QVBoxLayout *vlayout; // A layout for the video and the control bar QWidget *mainWidget; // The main widget QTimer *timer; // A timer for animation bool b_isexpanded; // Is the control bar expanded QPropertyAnimation *animation; // Animation when expanding control bar public slots : void collapseControlBar (); void expandControlBar(); }; #endif // MAINWINDOW_HPP
mainwindow.cpp
#include "mainwindow.hpp" MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) { setContentsMargins(0, 0, 0, 0); fakecontent = new QPixmap(); fakecontent->load( "a/path/to/cute/kitten.jpg" ); video = new QLabel(); video->setPixmap( *fakecontent ); b_isexpanded = false; controlbar = new QQuickWidget(); controlbar->setSource( QUrl( QStringLiteral( "ControlBar.qml" )) ); controlbar->setResizeMode(QQuickWidget::SizeRootObjectToView); controlbar->setMaximumHeight( 0 ); vlayout = new QVBoxLayout( ); vlayout->addWidget(video); vlayout->addWidget(controlbar); mainWidget = new QWidget(); mainWidget->setLayout(vlayout); setCentralWidget(mainWidget); qApp->installEventFilter(this); timer = new QTimer(); timer->setInterval(5000); connect( timer, SIGNAL(timeout()), this, SLOT(collapseControlBar()) ); animation = new QPropertyAnimation(this, "size"); animation->setDuration(300); } MainWindow::~MainWindow() { delete fakecontent; delete video; delete controlbar; delete vlayout; delete mainWidget; delete timer; } bool MainWindow::eventFilter(QObject *obj, QEvent *event) { if (obj == this && event->type() == QEvent::Resize) { video->setPixmap( fakecontent->scaled(video->size()) ); } else if (obj == video && event->type() == QEvent::MouseMove) { expandControlBar(); } return false; } void MainWindow::collapseControlBar() { this->resize(this->size().width(), video->size().height() + 20); b_isexpanded = false; controlbar->setMaximumHeight( 0 ); } void MainWindow::expandControlBar() { if (b_isexpanded) { timer->stop(); timer->start(); } else { animation->setStartValue( this->size() ); animation->setEndValue( QSize( this->size().width(), video->size().height() + 120 ) ); animation->start(); timer->start(); b_isexpanded = true; controlbar->setMaximumHeight( 100 ); } }
ControlBar.qml
import QtQuick 2.0 Item { Rectangle { anchors.fill: parent color: "#00FF00" } }
-
I'm replying after a while because I tryed a lot of stuff since, and I don't want to let this topic falling unanswered in the abyss of the forum. The best solution I've came up with so far is using the resize function on both the main window and the control bar.
At the end of the post there is a working code of a fake video displayed with a control bar under it when the mouse hover the "video" for those interested. I've added an eventfilter to resize the "video" every time the main window is resized as this is how work my video (it made thing a bit harder)
This version is working by using setMaximumHeight() on the control bar, it works because when the window is resized either the "video" takes more space or the control bar takes more space, qt choose to expand the bottom one. For more consistency, it's also possible to use setFixedHeight() on the controlBar but you can"t animate it as easily.
main.cpp
#include "mainwindow.hpp" #include <QApplication> int main(int argc, char *argv[]) { QApplication a(argc, argv); MainWindow w; w.show(); return a.exec(); }
mainwindow.hpp
#ifndef MAINWINDOW_HPP #define MAINWINDOW_HPP #include <QMainWindow> #include <QtQml> #include <QtQuickWidgets/QQuickWidget> #include <QHBoxLayout> #include <QLabel> #include <QTimer> class MainWindow : public QMainWindow { Q_OBJECT public: MainWindow(QWidget *parent = 0); bool eventFilter(QObject *obj, QEvent *event); ~MainWindow(); private: QPixmap *fakecontent; // An image that acts as the video QLabel *video; // The QWidget containing the "video" QQuickWidget *controlbar; // The control bar in QML QVBoxLayout *vlayout; // A layout for the video and the control bar QWidget *mainWidget; // The main widget QTimer *timer; // A timer for animation bool b_isexpanded; // Is the control bar expanded QPropertyAnimation *animation; // Animation when expanding control bar public slots : void collapseControlBar (); void expandControlBar(); }; #endif // MAINWINDOW_HPP
mainwindow.cpp
#include "mainwindow.hpp" MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) { setContentsMargins(0, 0, 0, 0); fakecontent = new QPixmap(); fakecontent->load( "a/path/to/cute/kitten.jpg" ); video = new QLabel(); video->setPixmap( *fakecontent ); b_isexpanded = false; controlbar = new QQuickWidget(); controlbar->setSource( QUrl( QStringLiteral( "ControlBar.qml" )) ); controlbar->setResizeMode(QQuickWidget::SizeRootObjectToView); controlbar->setMaximumHeight( 0 ); vlayout = new QVBoxLayout( ); vlayout->addWidget(video); vlayout->addWidget(controlbar); mainWidget = new QWidget(); mainWidget->setLayout(vlayout); setCentralWidget(mainWidget); qApp->installEventFilter(this); timer = new QTimer(); timer->setInterval(5000); connect( timer, SIGNAL(timeout()), this, SLOT(collapseControlBar()) ); animation = new QPropertyAnimation(this, "size"); animation->setDuration(300); } MainWindow::~MainWindow() { delete fakecontent; delete video; delete controlbar; delete vlayout; delete mainWidget; delete timer; } bool MainWindow::eventFilter(QObject *obj, QEvent *event) { if (obj == this && event->type() == QEvent::Resize) { video->setPixmap( fakecontent->scaled(video->size()) ); } else if (obj == video && event->type() == QEvent::MouseMove) { expandControlBar(); } return false; } void MainWindow::collapseControlBar() { this->resize(this->size().width(), video->size().height() + 20); b_isexpanded = false; controlbar->setMaximumHeight( 0 ); } void MainWindow::expandControlBar() { if (b_isexpanded) { timer->stop(); timer->start(); } else { animation->setStartValue( this->size() ); animation->setEndValue( QSize( this->size().width(), video->size().height() + 120 ) ); animation->start(); timer->start(); b_isexpanded = true; controlbar->setMaximumHeight( 100 ); } }
ControlBar.qml
import QtQuick 2.0 Item { Rectangle { anchors.fill: parent color: "#00FF00" } }
@MoaMoaK
Hi, this may be a stupid question, but why do you want to resize the Video-Widget in the first place?You could make the toolbar and the bottom button-bar its own Widget and just place it on top of the video-widget. With varying decrees of transparency and
Qt::FramelessWindowHint
set to true. -
@MoaMoaK
Hi, this may be a stupid question, but why do you want to resize the Video-Widget in the first place?You could make the toolbar and the bottom button-bar its own Widget and just place it on top of the video-widget. With varying decrees of transparency and
Qt::FramelessWindowHint
set to true.@J.Hilk
At the end, I would like both possibilities implemented. Having the controls under the video, allows you to see every pixel of the screen while still being able to manipulate the controls. For instance, in some cases, you may want to examine frame by frame a specific section of the video that would appear under the controls else. -
I'm replying after a while because I tryed a lot of stuff since, and I don't want to let this topic falling unanswered in the abyss of the forum. The best solution I've came up with so far is using the resize function on both the main window and the control bar.
At the end of the post there is a working code of a fake video displayed with a control bar under it when the mouse hover the "video" for those interested. I've added an eventfilter to resize the "video" every time the main window is resized as this is how work my video (it made thing a bit harder)
This version is working by using setMaximumHeight() on the control bar, it works because when the window is resized either the "video" takes more space or the control bar takes more space, qt choose to expand the bottom one. For more consistency, it's also possible to use setFixedHeight() on the controlBar but you can"t animate it as easily.
main.cpp
#include "mainwindow.hpp" #include <QApplication> int main(int argc, char *argv[]) { QApplication a(argc, argv); MainWindow w; w.show(); return a.exec(); }
mainwindow.hpp
#ifndef MAINWINDOW_HPP #define MAINWINDOW_HPP #include <QMainWindow> #include <QtQml> #include <QtQuickWidgets/QQuickWidget> #include <QHBoxLayout> #include <QLabel> #include <QTimer> class MainWindow : public QMainWindow { Q_OBJECT public: MainWindow(QWidget *parent = 0); bool eventFilter(QObject *obj, QEvent *event); ~MainWindow(); private: QPixmap *fakecontent; // An image that acts as the video QLabel *video; // The QWidget containing the "video" QQuickWidget *controlbar; // The control bar in QML QVBoxLayout *vlayout; // A layout for the video and the control bar QWidget *mainWidget; // The main widget QTimer *timer; // A timer for animation bool b_isexpanded; // Is the control bar expanded QPropertyAnimation *animation; // Animation when expanding control bar public slots : void collapseControlBar (); void expandControlBar(); }; #endif // MAINWINDOW_HPP
mainwindow.cpp
#include "mainwindow.hpp" MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) { setContentsMargins(0, 0, 0, 0); fakecontent = new QPixmap(); fakecontent->load( "a/path/to/cute/kitten.jpg" ); video = new QLabel(); video->setPixmap( *fakecontent ); b_isexpanded = false; controlbar = new QQuickWidget(); controlbar->setSource( QUrl( QStringLiteral( "ControlBar.qml" )) ); controlbar->setResizeMode(QQuickWidget::SizeRootObjectToView); controlbar->setMaximumHeight( 0 ); vlayout = new QVBoxLayout( ); vlayout->addWidget(video); vlayout->addWidget(controlbar); mainWidget = new QWidget(); mainWidget->setLayout(vlayout); setCentralWidget(mainWidget); qApp->installEventFilter(this); timer = new QTimer(); timer->setInterval(5000); connect( timer, SIGNAL(timeout()), this, SLOT(collapseControlBar()) ); animation = new QPropertyAnimation(this, "size"); animation->setDuration(300); } MainWindow::~MainWindow() { delete fakecontent; delete video; delete controlbar; delete vlayout; delete mainWidget; delete timer; } bool MainWindow::eventFilter(QObject *obj, QEvent *event) { if (obj == this && event->type() == QEvent::Resize) { video->setPixmap( fakecontent->scaled(video->size()) ); } else if (obj == video && event->type() == QEvent::MouseMove) { expandControlBar(); } return false; } void MainWindow::collapseControlBar() { this->resize(this->size().width(), video->size().height() + 20); b_isexpanded = false; controlbar->setMaximumHeight( 0 ); } void MainWindow::expandControlBar() { if (b_isexpanded) { timer->stop(); timer->start(); } else { animation->setStartValue( this->size() ); animation->setEndValue( QSize( this->size().width(), video->size().height() + 120 ) ); animation->start(); timer->start(); b_isexpanded = true; controlbar->setMaximumHeight( 100 ); } }
ControlBar.qml
import QtQuick 2.0 Item { Rectangle { anchors.fill: parent color: "#00FF00" } }
@MoaMoaK
Hi,
I was trying to run the code provided by you but i'm facing an error with this header file
**#include <QtQuickWidgets/QQuickWidget>" /home/ashutosh/Resize/mainwindow.hpp:6: error: QtQuickWidgets/QQuickWidget: No such file or directory
#include <QtQuickWidgets/QQuickWidget>"I'm not able tp locate this header file i q libraries. Do we need to install any other plugins or something else.
Thanks.
-
@MoaMoaK
Hi,
I was trying to run the code provided by you but i'm facing an error with this header file
**#include <QtQuickWidgets/QQuickWidget>" /home/ashutosh/Resize/mainwindow.hpp:6: error: QtQuickWidgets/QQuickWidget: No such file or directory
#include <QtQuickWidgets/QQuickWidget>"I'm not able tp locate this header file i q libraries. Do we need to install any other plugins or something else.
Thanks.
@Ashutosh_Sachdeva What Qt version do you use?
Also you should just include QQuickWidget:#include <QQuickWidget>
-
@jsulm
i'm using QT 5.12.1.I tried including only <QQuickWidget> but it's showing the same error
-
@jsulm
i'm using QT 5.12.1.I tried including only <QQuickWidget> but it's showing the same error
@Ashutosh_Sachdeva How did you install Qt?
-
@Ashutosh_Sachdeva How did you install Qt?
@jsulm
https://wiki.qt.io/Install_Qt_5_on_UbuntuThrough this link
-
@jsulm
https://wiki.qt.io/Install_Qt_5_on_UbuntuThrough this link
@Ashutosh_Sachdeva So, you used offline installer? And you really installed Qt 5.12.1, not 5.7?
Was there anything to select during installation? -
Hi,
Sorry it's 5.13.1.
Yes i used the offline installer and there were many option and i selected the latest one.
-
Hi,
Sorry it's 5.13.1.
Yes i used the offline installer and there were many option and i selected the latest one.
@Ashutosh_Sachdeva Not sure, I don't use offline installer. My Qt setup was made via online installer and I have the headers.
-
@Ashutosh_Sachdeva Not sure, I don't use offline installer. My Qt setup was made via online installer and I have the headers.
@jsulm Ok
I have tried updating the lib. but that doesn't worked any other suggestion or solution?
-
@jsulm Ok
I have tried updating the lib. but that doesn't worked any other suggestion or solution?
@Ashutosh_Sachdeva You can try online installer to install Qt. My Qt setup installed using online installer has this header file.
Also as stated in your other thread make sure you haveQT += quickwidgets
in your pro file.