Poszperałem trochę w dokumentacji i googlach i napisałem klasę odpowiedzialną za wyłapywanie zdarzenia zmiany rozmiaru.
Plik resizingcapturer.h
#ifndef RESIZINGCAPTURER_H
#define RESIZINGCAPTURER_H
#include <QObject>
#include <QEvent>
class ResizingCapturer : public QObject
{
Q_OBJECT
public:
QList <QWidget *> widgets;
ResizingCapturer(QList <QWidget *> childrenList);
protected:
bool eventFilter(QObject *obj, QEvent *event);
};
#endif // RESIZINGCAPTURER_H
Plik resizingcapturer.cpp
#include "resizingcapturer.h"
#include <QDebug>
#include <QObject>
#include <QEvent>
#include <QResizeEvent>
#include <QMouseEvent>
#include <QWidget>
ResizingCapturer::ResizingCapturer(QList <QWidget *> childrenList)
{
widgets = childrenList;
}
bool ResizingCapturer::eventFilter(QObject *obj, QEvent *event)
{
if (event->type() == QEvent::Resize)
{
QResizeEvent *resizeEvent = static_cast <QResizeEvent *>(event);
for(int i=0; i<widgets.size(); i++)
{
qDebug()<<"i= "<<i;
// MainWindow sizes
int Width_1 = resizeEvent->oldSize().width();
int Height_1 = resizeEvent->oldSize().height();
int Width_2 = resizeEvent->size().width();
int Height_2 = resizeEvent->size().height();
// widget old sizes
int width_1 = widgets[i] -> width();
int height_1 = widgets[i] -> height();
// new widget geometry
int x = widgets[i] -> x() * Width_2 / Width_1;
int y = widgets[i] -> y() * Height_2 / Height_1;
int width_2 = width_1 * Width_2 / Width_1;
int height_2 = height_1 * Height_2 / Height_1;
widgets[i] -> setGeometry(x,y,width_2,height_2);
qDebug()<<"Resizing\n";
qDebug()<<"Width_1 = "<<Width_1;
qDebug()<<"Height_1= "<<Height_1;
qDebug()<<"Width_2 = "<<Width_2;
qDebug()<<"Height_2= "<<Height_2;
qDebug()<<"width_1 = "<<width_1;
qDebug()<<"height_1= "<<height_1;
qDebug()<<"x = "<<x;
qDebug()<<"y = "<<y;
qDebug()<<"width_2 = "<<width_2;
qDebug()<<"height_2 = "<<height_2;
}
return true;
}
// standard event processing
return QObject::eventFilter(obj, event);
}
main.cpp
#include "mainwindow.h"
#include "keypresseater.h"
#include "resizingcapturer.h"
#include <QApplication>
#include <QWidget>
#include <QLineEdit>
#include <QDebug>
#include <QList>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
QPushButton *przycisk = new QPushButton("Siemanko", &w);
przycisk->setGeometry(10,10,120,20);
przycisk->show();
// pobieram wszystkie dzieci głównego okna
QList <QWidget *> childrens = w.findChildren <QWidget *> ();
qDebug() << "childrens[0]->width() " << childrens[0]->x();
qDebug() << "childrens[0]->width() " << childrens[0]->y();
qDebug() << "childrens[0]->width() " << childrens[0]->width();
qDebug() << "childrens[0]->width() " << childrens[0]->height();
ResizingCapturer *resizingCapturer = new ResizingCapturer(childrens);
w.show();
w.installEventFilter(resizingCapturer);
return a.exec();
}
Tylko problem w tym, że za pojedyncze zdarzenie zmiany rozmiaru uznaje się zmianę tego rozmiaru choćby o jeden piksel. Czyli jeśli okno główne ma szerokość 500, a ja je rozciągnę na tysiąc to nie jest tak, że:
oldSize().width() = 500 a size().width() = 1000
tylko:
oldSize().width() = 500 a size().width() = 501
oldSize().width() = 501 a size().width() = 502
...
Czyli zdarzenie się wywołuje 500 razy i moje wzory, gdzie wymnażam dotychczasowe rozmiary widżetów przez skalę podobieństwa nowego okna do starego nie zadziałają bo wtedy jest:
roz_widzeta = roz_widzeta * 501/500;
nawet gdy zmienię wszystkie inty na np. floaty (zrobiłem to przed chwilą) to i tak nic nie daje bo
501/500 to 1.002
więc dla buttona o szerokości 200 mamy:
roz_widzeta = 200 * 1.002 czyli 200.4
a zmienna roz_widzeta musi być typu int więc część ułamkowa zostanie obcięta i będzie nadal 200.
Z kolei jak zmniejszam to mam np
roz_widzeta = 200 * 0.998 czyli 199.6 czyli tak naprawdę 199 co oznacza, że rozmiary kontrolek zmieniają się o tyle samo co okna głównego i w końcu mają któryś wymiar równy 0 i znikają (np. zmniejszę szerokość okna z 500 na 481 to lineEdit o szerokości 20 będzie miał szerokość 1, przeciągnę jeszcze trochę to zniknie).
Myślałem o sprawdzaniu zdarzenia MousePressButton i kombinowaniu z tym, ale ono nie jest aktywne gdy kursor myszki jest na brzegu tylko na oknie. Kodzę w Qt od niedawna. Ktoś ma jakieś sugestie jak można poprawić mój kod?