Hello all, 

This took me a while to figure out, so I thought I would share it with the list 
for others needing similar functionality.

I was working on a small program in which I wanted two panes: the left should 
contain a QTextEdit and a QPushButton and the right should contain an image 
generated from the input on the left. I wanted the image on the right to be as 
large as possible while maintaining the original aspect ratio. The image is an 
SVG generated by Graphviz (http://graphviz.org/) and pydot 
(https://code.google.com/p/pydot/). Here is a link to a screenshot 
(http://seanfisk.github.com/database-serializability-graph/screenshot.png) of 
how it looks.

After messing around with layouts quite a bit, I realized that the right way to 
do it was to render the SVG on a restricted part of the canvas. QSvgWidget, 
which is a thin wrapper around QSvgRenderer, renders the SVG as large as 
possible without aspect ratio by default. This code does the trick to keep the 
SVG at the default aspect ratio:
from __future__ import division from PySide import QtCore, QtGui, QtSvg class 
AspectRatioSvgWidget(QtSvg.QSvgWidget): def paintEvent(self, paint_event): 
painter = QtGui.QPainter(self) default_width, default_height = 
self.renderer().defaultSize().toTuple() widget_width, widget_height = 
self.size().toTuple() ratio_x = widget_width / default_width ratio_y = 
widget_height / default_height if ratio_x < ratio_y: new_width = widget_width 
new_height = widget_width * default_height / default_width new_left = 0 new_top 
= (widget_height - new_height) / 2 else: new_width = widget_height * 
default_width / default_height new_height = widget_height new_left = 
(widget_width - new_width) / 2 new_top = 0 self.renderer().render( painter, 
QtCore.QRectF(new_left, new_top, new_width, new_height))

The key to this was realizing the default width of the SVG (which implicitly 
indicates the aspect ratio) can be accessed using 
self.renderer().defaultSize(). Now when the window is resized the SVG is as 
large as possible while maintaing the ratio.
I also have code laying around for a centered bitmap (e.g., PNG) which 
maintains its original aspect ratio. Given the choice between SVG and PNG, 
though, SVG was the clear winner. Kudos to Qt and PySide for having awesome SVG 
support too!
The full code is available on Github 
(https://github.com/seanfisk/database-serializability-graph) under 
serial_graph/gui.py. Hope this helps someone out!

Sincerely,

-- 
Sean Fisk

_______________________________________________
PySide mailing list
[email protected]
http://lists.qt-project.org/mailman/listinfo/pyside

Reply via email to