I’m working on a Qt application where I have an overlay window that needs to maintain a square aspect ratio regardless of how it is resized. My app has two windows open at the same time and both are top-level windows. I want the overlay window which is a QFrame to stay as a square when resized from corner.
This is the code for my overlay window class:
#include "overlaywindow.h"
OverlayWindow::OverlayWindow(QFrame* parent) :
QFrame(parent),
m_isMeasurementRunning(false),
m_aspectRatio(1.0)
{
// Set initial appearance, and behavior of the overlay window.
setWindowOpacity(0.5);
setStyleSheet("border: 1.5px solid black;background-color:#A9A9A9;");
setCursor(Qt::SizeAllCursor);
setMinimumSize(50, 50);
// Set maximum size based on the screen dimensions and position the window.
QRect screenRect = screen()->geometry();
setMaximumSize(screenRect.width(), screenRect.height());
setGeometry(screenRect.width() / 2 - 125, screenRect.height() / 2 - 125, 250, 250);
}
void OverlayWindow::setMeasurementState(bool state)
{
m_isMeasurementRunning = state;
// Adjust window properties based on the measurement state.
if (state)
{
setFixedSize(geometry().width(), geometry().width());
setCursor(Qt::ForbiddenCursor);
}
else
{
QRect screenRect = screen()->geometry();
setMaximumSize(screenRect.width(), screenRect.height());
setMinimumSize(50, 50);
setCursor(Qt::SizeAllCursor);
}
}
void OverlayWindow::mousePressEvent(QMouseEvent* event)
{
m_dragPos = event->pos();
}
void OverlayWindow::mouseMoveEvent(QMouseEvent* event)
{
if (m_isMeasurementRunning)
{
// Ignore mouse move events if measurement is running.
event->ignore();
}
else
{
// Move the window while dragging, ensuring it stays within screen bounds.
if (checkBounds(event))
{
move(
event->globalPosition().x() - m_dragPos.x(),
event->globalPosition().y() - m_dragPos.y());
}
}
}
void OverlayWindow::resizeEvent(QResizeEvent* event)
{
// Maintain aspect ratio by making the window square during resize.
if (event->size().width() != event->oldSize().width())
{
resize(event->size().height(), event->size().height());
}
else
{
resize(event->size().width(), event->size().width());
}
}
And this is the controller:
#include "windowscontroller.h"
WindowsController::WindowsController(
MainWindow* mainWindow,
OverlayWindow* overlayWindow,
FrameCounter* framecounter,
QString logDirectory) :
m_mainWindow(mainWindow),
m_overlayWindow(overlayWindow),
m_fpslogger(logDirectory),
m_framecounter(framecounter),
m_exit(false),
m_commandLineExec(false)
{
// Connect signals from MainWindow to controller's slots
connect(
m_mainWindow,
&MainWindow::measurementToggled,
this,
&WindowsController::onToggleMeasurement);
connect(m_mainWindow, &MainWindow::exitRequested, this, &WindowsController::onExitRequested);
// Connect signals from OverlayWindow to controller's slots
connect(
m_overlayWindow,
&OverlayWindow::exitRequested,
this,
&WindowsController::onExitRequested);
// Connect signals from FrameCounter to controller's slots
connect(m_framecounter, &FrameCounter::newfpsvalue, this, &WindowsController::updateDisplay);
}
void WindowsController::showWindows()
{
// Display the main window and the overlay window
m_mainWindow->setWindowFlags(Qt::Window);
m_overlayWindow->setWindowFlags(
Qt::Window | Qt::CustomizeWindowHint | Qt::WindowStaysOnTopHint);
m_overlayWindow->show();
m_mainWindow->show();
}
The current implementation uses the resizeEvent function to maintain the aspect ratio of the window as a square by setting the width and height to be equal. But when I try to resize from top or left the overlay window moves as well. And from what I understood heightForWidth() doesn’t work for top-level windows. I also tried multiple solution found in the forum like this one or this one but none seem to be working.
What modifications should I make to ensure that the overlay window always maintains a square aspect ratio, even when resized by the user?
Thank you!
ASM is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.