diff --git a/libs/flake/KoCanvasController.h b/libs/flake/KoCanvasController.h --- a/libs/flake/KoCanvasController.h +++ b/libs/flake/KoCanvasController.h @@ -349,7 +349,7 @@ void emitCanvasMousePositionChanged(const QPoint &position) { emit canvasMousePositionChanged(position); } void emitDocumentMousePositionChanged(const QPointF &position) { emit documentMousePositionChanged(position); } void emitSizeChanged(const QSize &size) { emit sizeChanged(size); } - void emitMoveDocumentOffset(const QPoint &point) { emit moveDocumentOffset(point); } + void emitMoveDocumentOffsetDevicePixel(const QPoint &point) { emit moveDocumentOffsetDevicePixel(point); } void emitZoomRelative(const qreal factor, const QPointF &stillPoint) { emit zoomRelative(factor, stillPoint); } // Convenience method to retrieve the canvas controller for who needs to use QPointer @@ -407,7 +407,7 @@ * @param point the new top-left point from which the document should * be drawn. */ - void moveDocumentOffset(const QPoint &point); + void moveDocumentOffsetDevicePixel(const QPoint &point); /** * Emitted when zoomRelativeToPoint have calculated a factor by which diff --git a/libs/flake/KoCanvasControllerWidget.cpp b/libs/flake/KoCanvasControllerWidget.cpp --- a/libs/flake/KoCanvasControllerWidget.cpp +++ b/libs/flake/KoCanvasControllerWidget.cpp @@ -55,7 +55,7 @@ // compensate. QPoint pt(q->horizontalScrollBar()->value(), q->verticalScrollBar()->value()); - q->proxyObject->emitMoveDocumentOffset(pt); + q->proxyObject->emitMoveDocumentOffsetDevicePixel(pt); QWidget *canvasWidget = canvas->canvasWidget(); @@ -86,11 +86,13 @@ int horizontalReserve = vastScrollingFactor * drawW; int verticalReserve = vastScrollingFactor * drawH; - int xMin = -horizontalReserve; - int yMin = -verticalReserve; + // HACK: Convert to device pixels + int xMin = static_cast(-horizontalReserve * viewportWidget->devicePixelRatioF()); + int yMin = static_cast(-verticalReserve * viewportWidget->devicePixelRatioF()); - int xMax = docW - drawW + horizontalReserve; - int yMax = docH - drawH + verticalReserve; + // HACK: Convert to device pixels + int xMax = static_cast(docW - (drawW + horizontalReserve) * viewportWidget->devicePixelRatioF()); + int yMax = static_cast(docH - (drawH + verticalReserve) * viewportWidget->devicePixelRatioF()); hScroll->setRange(xMin, xMax); vScroll->setRange(yMin, yMax); diff --git a/libs/ui/canvas/kis_canvas2.h b/libs/ui/canvas/kis_canvas2.h --- a/libs/ui/canvas/kis_canvas2.h +++ b/libs/ui/canvas/kis_canvas2.h @@ -292,7 +292,7 @@ * * @param documentOffset the offset in widget pixels */ - void documentOffsetMoved(const QPoint &documentOffset); + void documentDevicePixelOffsetMoved(const QPoint &documentOffset); void slotSelectionChanged(); diff --git a/libs/ui/canvas/kis_canvas2.cpp b/libs/ui/canvas/kis_canvas2.cpp --- a/libs/ui/canvas/kis_canvas2.cpp +++ b/libs/ui/canvas/kis_canvas2.cpp @@ -220,7 +220,7 @@ setLodAllowedInCanvas(m_d->lodAllowedInImage); m_d->animationPlayer = new KisAnimationPlayer(this); - connect(m_d->view->canvasController()->proxyObject, SIGNAL(moveDocumentOffset(QPoint)), SLOT(documentOffsetMoved(QPoint))); + connect(m_d->view->canvasController()->proxyObject, SIGNAL(moveDocumentOffsetDevicePixel(QPoint)), SLOT(documentDevicePixelOffsetMoved(QPoint))); connect(KisConfigNotifier::instance(), SIGNAL(configChanged()), SLOT(slotConfigChanged())); /** @@ -1049,10 +1049,10 @@ return m_d->view->image(); } -void KisCanvas2::documentOffsetMoved(const QPoint &documentOffset) +void KisCanvas2::documentDevicePixelOffsetMoved(const QPoint &documentOffset) { QPointF offsetBefore = m_d->coordinatesConverter->imageRectInViewportPixels().topLeft(); - m_d->coordinatesConverter->setDocumentOffset(documentOffset); + m_d->coordinatesConverter->setDocumentOffsetDevicePixel(documentOffset); QPointF offsetAfter = m_d->coordinatesConverter->imageRectInViewportPixels().topLeft(); QPointF moveOffset = offsetAfter - offsetBefore; diff --git a/libs/ui/canvas/kis_coordinates_converter.h b/libs/ui/canvas/kis_coordinates_converter.h --- a/libs/ui/canvas/kis_coordinates_converter.h +++ b/libs/ui/canvas/kis_coordinates_converter.h @@ -59,10 +59,11 @@ KisCoordinatesConverter(); ~KisCoordinatesConverter() override; - void setCanvasWidgetSize(QSize size); + void setCanvasWidgetSize(QSize size, qreal devicePixelRatio); void setDevicePixelRatio(qreal value); void setImage(KisImageWSP image); - void setDocumentOffset(const QPoint &offset); + void setDocumentOffsetDevicePixel(const QPoint &offset); +// void setDocumentOffsetLogicalPixel(const QPoint &offset); QPoint documentOffset() const; qreal rotationAngle() const; @@ -158,6 +159,9 @@ void correctTransformationToOffset(); void recalculateTransformations(); + QSizeF canvasWidgetLogicalPixelSize() const; + QPointF documentOffsetLogicalPixel() const; + private: struct Private; Private * const m_d; diff --git a/libs/ui/canvas/kis_coordinates_converter.cpp b/libs/ui/canvas/kis_coordinates_converter.cpp --- a/libs/ui/canvas/kis_coordinates_converter.cpp +++ b/libs/ui/canvas/kis_coordinates_converter.cpp @@ -42,9 +42,10 @@ bool isXAxisMirrored; bool isYAxisMirrored; qreal rotationAngle; - QSizeF canvasWidgetSize; +// QSizeF canvasWidgetSize; + QSize canvasWidgetDevicePixelSize; qreal devicePixelRatio; - QPointF documentOffset; + QPoint documentOffsetDevicePixel; QTransform flakeToWidget; QTransform imageToDocument; @@ -72,7 +73,8 @@ QSize documentSize = imageRectInWidgetPixels().toAlignedRect().size(); QPointF dPoint(documentSize.width(), documentSize.height()); - QPointF wPoint(m_d->canvasWidgetSize.width(), m_d->canvasWidgetSize.height()); + QSizeF wSize = canvasWidgetLogicalPixelSize(); + QPointF wPoint(wSize.width(), wSize.height()); QPointF minOffset = -cfg.vastScrolling() * wPoint; QPointF maxOffset = dPoint - wPoint + cfg.vastScrolling() * wPoint; @@ -105,14 +107,14 @@ void KisCoordinatesConverter::correctOffsetToTransformation() { - m_d->documentOffset = -(imageRectInWidgetPixels().topLeft() - - centeringCorrection()).toPoint(); + m_d->documentOffsetDevicePixel = -((imageRectInWidgetPixels().topLeft() - + centeringCorrection()) * m_d->devicePixelRatio).toPoint(); } void KisCoordinatesConverter::correctTransformationToOffset() { QPointF topLeft = imageRectInWidgetPixels().topLeft(); - QPointF diff = (-topLeft) - m_d->documentOffset; + QPointF diff = (-topLeft) - documentOffsetLogicalPixel(); diff += centeringCorrection(); m_d->flakeToWidget *= QTransform::fromTranslate(diff.x(), diff.y()); } @@ -131,7 +133,7 @@ correctTransformationToOffset(); QRectF irect = imageRectInWidgetPixels(); - QRectF wrect = QRectF(QPoint(0,0), m_d->canvasWidgetSize); + QRectF wrect = QRectF(QPoint(0,0), canvasWidgetLogicalPixelSize()); QRectF rrect = irect & wrect; QTransform reversedTransform = flakeToWidgetTransform().inverted(); @@ -141,6 +143,16 @@ m_d->widgetToViewport = reversedTransform * QTransform::fromTranslate(-offset.x(), -offset.y()); } +QSizeF KisCoordinatesConverter::canvasWidgetLogicalPixelSize() const +{ + return QSizeF(m_d->canvasWidgetDevicePixelSize) / m_d->devicePixelRatio; +} + +QPointF KisCoordinatesConverter::documentOffsetLogicalPixel() const +{ + return QPointF(m_d->documentOffsetDevicePixel) / m_d->devicePixelRatio; +} + KisCoordinatesConverter::KisCoordinatesConverter() : m_d(new Private) { } @@ -150,14 +162,27 @@ delete m_d; } -void KisCoordinatesConverter::setCanvasWidgetSize(QSize size) +void KisCoordinatesConverter::setCanvasWidgetSize(QSize size, qreal devicePixelRatio) { - m_d->canvasWidgetSize = size; + qDebug() << "KisCoordinatesConverter::setCanvasWidgetSize" << size << devicePixelRatio; +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wfloat-equal" + // This comparison is fine. We expect devicePixelRatio to be exactly identical. + if (devicePixelRatio != m_d->devicePixelRatio) { +#pragma clang diagnostic pop + warnUI << "WARNING: KisCoordinatesConverter::setCanvasWidgetSize called with dpr" << devicePixelRatio << "but internal dpr is" << m_d->devicePixelRatio; + } + // This is how QOpenGLCanvas sets the FBO and the viewport size. If + // devicePixelRatio is non-integral, the result is truncated. + int viewportWidth = static_cast(size.width() * devicePixelRatio); + int viewportHeight = static_cast(size.height() * devicePixelRatio); + m_d->canvasWidgetDevicePixelSize = QSize(viewportWidth, viewportHeight); recalculateTransformations(); } void KisCoordinatesConverter::setDevicePixelRatio(qreal value) { + qDebug() << "KisCoordinatesConverter::setDevicePixelRatio" << m_d->devicePixelRatio << "to" << value; m_d->devicePixelRatio = value; } @@ -167,18 +192,41 @@ recalculateTransformations(); } -void KisCoordinatesConverter::setDocumentOffset(const QPoint& offset) -{ - QPointF diff = m_d->documentOffset - offset; - - m_d->documentOffset = offset; - m_d->flakeToWidget *= QTransform::fromTranslate(diff.x(), diff.y()); +void KisCoordinatesConverter::setDocumentOffsetDevicePixel(const QPoint &offset) +{ +// int physicalOffsetX = offset.x() * m_d->devicePixelRatio; +// int physicalOffsetY = offset.y() * m_d->devicePixelRatio; +// // These adjusted positions are in logical pixel but is aligned in device +// // pixel space for pixel-perfect rendering. +// qreal pixelPerfectOffsetX = physicalOffsetX / m_d->devicePixelRatio; +// qreal pixelPerfectOffsetY = physicalOffsetY / m_d->devicePixelRatio; +// // FIXME: This is a temporary hack for fixing the canvas under fractional +// // DPI scaling before a new coordinate system is introduced. +// QPointF offsetAdjusted(pixelPerfectOffsetX, pixelPerfectOffsetY); +// QPointF diff = m_d->documentOffset - offsetAdjusted; + QPoint diff = m_d->documentOffsetDevicePixel - offset; + + m_d->documentOffsetDevicePixel = offset; + m_d->flakeToWidget *= QTransform::fromTranslate(diff.x() / m_d->devicePixelRatio, diff.y() / m_d->devicePixelRatio); + qDebug() << "offset:" << offset +// << "offsetAdjusted:" << offsetAdjusted +// << "documentOffset:" << m_d->documentOffset + << "documentOffsetDevicePixel" << m_d->documentOffsetDevicePixel + << "flakeToWidget:" << m_d->flakeToWidget; recalculateTransformations(); } +//void KisCoordinatesConverter::setDocumentOffsetLogicalPixel(const QPoint &offset) +//{ +// int physicalOffsetX = static_cast(offset.x() * m_d->devicePixelRatio); +// int physicalOffsetY = static_cast(offset.y() * m_d->devicePixelRatio); +// setDocumentOffsetDevicePixel(QPoint(physicalOffsetX, physicalOffsetY)); +//} + QPoint KisCoordinatesConverter::documentOffset() const { - return QPoint(int(m_d->documentOffset.x()), int(m_d->documentOffset.y())); + QPointF offset = documentOffsetLogicalPixel(); + return QPoint(int(offset.x()), int(offset.y())); } qreal KisCoordinatesConverter::rotationAngle() const @@ -218,7 +266,7 @@ correctOffsetToTransformation(); recalculateTransformations(); - return m_d->documentOffset.toPoint(); + return documentOffsetLogicalPixel().toPoint(); } QPoint KisCoordinatesConverter::mirror(QPointF center, bool mirrorXAxis, bool mirrorYAxis) @@ -259,7 +307,7 @@ correctOffsetToTransformation(); recalculateTransformations(); - return m_d->documentOffset.toPoint(); + return documentOffsetLogicalPixel().toPoint(); } bool KisCoordinatesConverter::xAxisMirrored() const @@ -285,7 +333,7 @@ correctOffsetToTransformation(); recalculateTransformations(); - return m_d->documentOffset.toPoint(); + return documentOffsetLogicalPixel().toPoint(); } QTransform KisCoordinatesConverter::imageToWidgetTransform() const{ @@ -415,12 +463,12 @@ QRectF KisCoordinatesConverter::widgetRectInFlakePixels() const { - return widgetToFlake(QRectF(QPoint(0,0), m_d->canvasWidgetSize)); + return widgetToFlake(QRectF(QPoint(0,0), canvasWidgetLogicalPixelSize())); } QRectF KisCoordinatesConverter::widgetRectInImagePixels() const { - return widgetToImage(QRectF(QPoint(0,0), m_d->canvasWidgetSize)); + return widgetToImage(QRectF(QPoint(0,0), canvasWidgetLogicalPixelSize())); } QPointF KisCoordinatesConverter::flakeCenterPoint() const @@ -432,7 +480,8 @@ QPointF KisCoordinatesConverter::widgetCenterPoint() const { - return QPointF(m_d->canvasWidgetSize.width() / 2.0, m_d->canvasWidgetSize.height() / 2.0); + QSizeF size = canvasWidgetLogicalPixelSize(); + return QPointF(size.width() / 2.0, size.height() / 2.0); } void KisCoordinatesConverter::imageScale(qreal *scaleX, qreal *scaleY) const diff --git a/libs/ui/canvas/kis_qpainter_canvas.cpp b/libs/ui/canvas/kis_qpainter_canvas.cpp --- a/libs/ui/canvas/kis_qpainter_canvas.cpp +++ b/libs/ui/canvas/kis_qpainter_canvas.cpp @@ -240,7 +240,7 @@ size.setHeight(1); } - coordinatesConverter()->setCanvasWidgetSize(size); + coordinatesConverter()->setCanvasWidgetSize(size, devicePixelRatioF()); m_d->prescaledProjection->notifyCanvasSizeChanged(size); } diff --git a/libs/ui/opengl/kis_opengl_canvas2.h b/libs/ui/opengl/kis_opengl_canvas2.h --- a/libs/ui/opengl/kis_opengl_canvas2.h +++ b/libs/ui/opengl/kis_opengl_canvas2.h @@ -119,6 +119,7 @@ void drawImage(); void drawCheckers(); void drawGrid(); + QSize viewportDevicePixelSize() const; private: diff --git a/libs/ui/opengl/kis_opengl_canvas2.cpp b/libs/ui/opengl/kis_opengl_canvas2.cpp --- a/libs/ui/opengl/kis_opengl_canvas2.cpp +++ b/libs/ui/opengl/kis_opengl_canvas2.cpp @@ -384,7 +384,7 @@ void KisOpenGLCanvas2::resizeGL(int width, int height) { - coordinatesConverter()->setCanvasWidgetSize(QSize(width, height)); + coordinatesConverter()->setCanvasWidgetSize(QSize(width, height), devicePixelRatioF()); paintGL(); } @@ -591,9 +591,15 @@ return; } + QSize viewportSize = viewportDevicePixelSize(); + qreal pixelPerfectScaledWidth = viewportSize.width() / devicePixelRatioF(); + qreal pixelPerfectScaledHeight = viewportSize.height() / devicePixelRatioF(); + QMatrix4x4 projectionMatrix; projectionMatrix.setToIdentity(); - projectionMatrix.ortho(0, width(), height(), 0, NEAR_VAL, FAR_VAL); + // FIXME: It is probably better to have the projection in device pixel, but + // this requires introducing a new coordinate system. + projectionMatrix.ortho(0, pixelPerfectScaledWidth, pixelPerfectScaledHeight, 0, NEAR_VAL, FAR_VAL); // Set view/projection matrices QMatrix4x4 modelMatrix(coordinatesConverter()->imageToWidgetTransform()); @@ -613,7 +619,7 @@ d->lineBuffer.bind(); } - QRectF widgetRect(0,0, width(), height()); + QRectF widgetRect(0,0, pixelPerfectScaledWidth, pixelPerfectScaledHeight); QRectF widgetRectInImagePixels = coordinatesConverter()->documentToImage(coordinatesConverter()->widgetToDocument(widgetRect)); QRect wr = widgetRectInImagePixels.toAlignedRect(); @@ -666,9 +672,15 @@ d->displayShader->bind(); + QSize viewportSize = viewportDevicePixelSize(); + qreal pixelPerfectScaledWidth = viewportSize.width() / devicePixelRatioF(); + qreal pixelPerfectScaledHeight = viewportSize.height() / devicePixelRatioF(); + QMatrix4x4 projectionMatrix; projectionMatrix.setToIdentity(); - projectionMatrix.ortho(0, width(), height(), 0, NEAR_VAL, FAR_VAL); + // FIXME: It is probably better to have the projection in device pixel, but + // this requires introducing a new coordinate system. + projectionMatrix.ortho(0, pixelPerfectScaledWidth, pixelPerfectScaledHeight, 0, NEAR_VAL, FAR_VAL); // Set view/projection matrices QMatrix4x4 modelMatrix(converter->imageToWidgetTransform()); @@ -680,7 +692,7 @@ textureMatrix.setToIdentity(); d->displayShader->setUniformValue(d->displayShader->location(Uniform::TextureMatrix), textureMatrix); - QRectF widgetRect(0,0, width(), height()); + QRectF widgetRect(0,0, pixelPerfectScaledWidth, pixelPerfectScaledHeight); QRectF widgetRectInImagePixels = converter->documentToImage(converter->widgetToDocument(widgetRect)); const QRect renderingLimit = canvas()->renderingLimit(); @@ -838,6 +850,15 @@ glDisable(GL_BLEND); } +QSize KisOpenGLCanvas2::viewportDevicePixelSize() const +{ + // This is how QOpenGLCanvas sets the FBO and the viewport size. If + // devicePixelRatioF() is non-integral, the result is truncated. + int viewportWidth = static_cast(width() * devicePixelRatioF()); + int viewportHeight = static_cast(height() * devicePixelRatioF()); + return QSize(viewportWidth, viewportHeight); +} + void KisOpenGLCanvas2::slotConfigChanged() { KisConfig cfg(true); diff --git a/libs/ui/tests/kis_coordinates_converter_test.cpp b/libs/ui/tests/kis_coordinates_converter_test.cpp --- a/libs/ui/tests/kis_coordinates_converter_test.cpp +++ b/libs/ui/tests/kis_coordinates_converter_test.cpp @@ -44,8 +44,8 @@ initImage(&image, &converter); converter.setImage(image); - converter.setDocumentOffset(QPoint(20,20)); - converter.setCanvasWidgetSize(QSize(500,500)); + converter.setDocumentOffsetDevicePixel(QPoint(20,20)); + converter.setCanvasWidgetSize(QSize(500,500), 1.0); converter.setZoom(1.); QRectF testRect(100,100,100,100); @@ -84,8 +84,8 @@ initImage(&image, &converter); converter.setImage(image); - converter.setDocumentOffset(QPoint(0,0)); - converter.setCanvasWidgetSize(QSize(500,500)); + converter.setDocumentOffsetDevicePixel(QPoint(0,0)); + converter.setCanvasWidgetSize(QSize(500,500), 1.0); converter.setZoom(1.); @@ -104,8 +104,8 @@ initImage(&image, &converter); converter.setImage(image); - converter.setDocumentOffset(QPoint(20,30)); - converter.setCanvasWidgetSize(QSize(500,500)); + converter.setDocumentOffsetDevicePixel(QPoint(20,30)); + converter.setCanvasWidgetSize(QSize(500,500), 1.0); QRectF testRect(100,100,100,100); QTransform imageToWidget; @@ -145,8 +145,8 @@ initImage(&image, &converter); converter.setImage(image); - converter.setDocumentOffset(QPoint(20,30)); - converter.setCanvasWidgetSize(QSize(500,500)); + converter.setDocumentOffsetDevicePixel(QPoint(20,30)); + converter.setCanvasWidgetSize(QSize(500,500), 1.0); QRectF testRect(100,100,100,100); QTransform imageToWidget; @@ -178,8 +178,8 @@ QRectF testRect(800, 100, 300, 300); converter.setImage(image); - converter.setDocumentOffset(QPoint(0,0)); - converter.setCanvasWidgetSize(widgetSize); + converter.setDocumentOffsetDevicePixel(QPoint(0,0)); + converter.setCanvasWidgetSize(widgetSize, 1.0); converter.rotate(converter.widgetCenterPoint(), 30); converter.setZoom(1.); @@ -212,8 +212,8 @@ QRectF testRect(300, 100, 200, 200); converter.setImage(image); - converter.setDocumentOffset(QPoint(200,100)); - converter.setCanvasWidgetSize(widgetSize); + converter.setDocumentOffsetDevicePixel(QPoint(200,100)); + converter.setCanvasWidgetSize(widgetSize, 1.0); // QTransform imageToWidget; // QTransform documentToWidget; @@ -246,8 +246,8 @@ QRectF testRect(300, 100, 200, 200); converter.setImage(image); - converter.setDocumentOffset(QPoint(-50,-50)); - converter.setCanvasWidgetSize(widgetSize); + converter.setDocumentOffsetDevicePixel(QPoint(-50,-50)); + converter.setCanvasWidgetSize(widgetSize, 1.0); // QTransform imageToWidget; // QTransform documentToWidget; diff --git a/libs/ui/tests/kis_prescaled_projection_test.cpp b/libs/ui/tests/kis_prescaled_projection_test.cpp --- a/libs/ui/tests/kis_prescaled_projection_test.cpp +++ b/libs/ui/tests/kis_prescaled_projection_test.cpp @@ -297,8 +297,8 @@ converter.setResolution(100, 100); converter.setZoom(1.); converter.setImage(image); - converter.setCanvasWidgetSize(QSize(100,100)); - converter.setDocumentOffset(QPoint(100,100)); + converter.setCanvasWidgetSize(QSize(100,100), 1.0); + converter.setDocumentOffsetDevicePixel(QPoint(100,100)); projection.setCoordinatesConverter(&converter); projection.setMonitorProfile(0, @@ -327,7 +327,7 @@ QVERIFY(TestUtil::compareQImages(pt, result, reference)); // Test actual scrolling - t.converter.setDocumentOffset(QPoint(150,150)); + t.converter.setDocumentOffsetDevicePixel(QPoint(150,150)); t.projection.viewportMoved(QPoint(-50,-50)); result = t.projection.prescaledQImage(); @@ -341,9 +341,9 @@ { PrescaledProjectionTester t; - t.converter.setDocumentOffset(QPoint(0,0)); + t.converter.setDocumentOffsetDevicePixel(QPoint(0,0)); - t.converter.setCanvasWidgetSize(QSize(300,300)); + t.converter.setCanvasWidgetSize(QSize(300,300), 1.0); t.projection.notifyCanvasSizeChanged(QSize(300,300)); QEXPECT_FAIL("", "Images should be the same, but aren't", Continue); @@ -361,7 +361,7 @@ "testScrollingZoom50", "zoom50")); - t.converter.setDocumentOffset(QPoint(50,50)); + t.converter.setDocumentOffsetDevicePixel(QPoint(50,50)); t.projection.viewportMoved(QPoint(-50,-50)); QEXPECT_FAIL("", "Images should be the same, but aren't", Continue); @@ -375,9 +375,9 @@ { PrescaledProjectionTester t; - t.converter.setDocumentOffset(QPoint(10,10)); + t.converter.setDocumentOffsetDevicePixel(QPoint(10,10)); - t.converter.setCanvasWidgetSize(2*QSize(300,300)); + t.converter.setCanvasWidgetSize(2*QSize(300,300), 1.0); t.projection.notifyCanvasSizeChanged(2*QSize(300,300));