PyQt and QGridLayout

325 views
Skip to first unread message

David Martinez

unread,
Mar 19, 2014, 8:17:05 AM3/19/14
to python_in...@googlegroups.com
Hi,

I'm trying to get a window displaying a grid of images. (Like the ones that would exist in either a character loader or a pose manager). Each of those buttons would execute or import a different file.

I want the QGridLayout to react to the size of the window. In order to do that, this is what I've done:
  • Created a main layout for the window
  • Created a QScrollArea (Since I want to get a vertical scroll bar if the grid has too many rows to be displayed with the current size)
  • Created a QWidget inside the QScrollArea so I can add a layout to it
  • Created a QGridLayout within the QWidget previously created (This one will contain the buttons)

At the moment, I'm overwritting the 'resizeEvent' method of the window to calculate how many rows and columns I'm going to need and I re-draw the rowss and columns of buttons based on the result.

For some reason, I have the feeling that I might be re-inventing the wheel and there might be an easier way to do this. That's why I'm sending this message.  :-)

This is the code that I have so far:

- https://gist.github.com/davidmartinezanim/9640295

Also there are a few questions that I have:

  • I'm not sure if the current method is really intensive on the computer. (Of it it is the best one to use for that matter).
  • Ideally, I want to implement a MVP solution. (Displaying the information using images will be only one of the options). Should I scratch my current code or will it be usable?
  • I want to be able to add borders to the image (of different colors depending of status of characters). My plan was to flatten the button, change it's background color and add a Pixmap on top so the background of the button will act as border and the image will be on top. Is that a good approach?
  • I'd like to have the grid aligned to the left and not adding spacing between buttons when increasing the width of the window. New columns and rows should be added if necessary but not this strange spacing that I'm getting right now. The spacing between buttons should be the same regardless of the size of the window.

I know that there are quite a few questions in this email and I intend to start fixing things one step at a time, but I wanted to check with you guys if I'm going in the right direction or not.

Many thanks in advance


--
David Martinez - Technical Animator
 

Justin Israel

unread,
Mar 19, 2014, 3:56:49 PM3/19/14
to python_in...@googlegroups.com
I think you are reinventing the wheel. The PyQt4 source comes with a flowlayout in its example directory:

I actually ported that to a QGraphicsLayout and use it for images in a grid. Works great. 


--
You received this message because you are subscribed to the Google Groups "Python Programming for Autodesk Maya" group.
To unsubscribe from this group and stop receiving emails from it, send an email to python_inside_m...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/python_inside_maya/CAMLeNpxVO57NYLzudWa7SZE_AOEAucJayBBy3%2Bx0afNNrBjcPA%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.

David Martinez

unread,
Mar 19, 2014, 4:27:48 PM3/19/14
to python_in...@googlegroups.com
Ah, I thought that might have been the case! I will take a look and see how it goes.
I will try to go one step at a time instead of trying to get the whole thing working.

Thanks again Justin


--
David Martinez - Technical Animator



David Martinez

unread,
Mar 19, 2014, 5:33:40 PM3/19/14
to python_in...@googlegroups.com
Wait... Does your implementation use the FlowLayout at all then?



--
David Martinez - Technical Animator
 


Fredrik Averpil

unread,
Mar 19, 2014, 6:31:27 PM3/19/14
to python_in...@googlegroups.com
+1 for flowlayout

I have a side project which hasn't gotten a lot of attention lately but you can see how I implemented it here: https://github.com/fredrikaverpil/pyVFX-viewer

// Fredrik

David Martinez

unread,
Mar 19, 2014, 7:16:54 PM3/19/14
to python_in...@googlegroups.com
Thanks for the heads up Fredik
I will take a look    :-)


--
David Martinez - Technical Animator
 


--
You received this message because you are subscribed to the Google Groups "Python Programming for Autodesk Maya" group.
To unsubscribe from this group and stop receiving emails from it, send an email to python_inside_m...@googlegroups.com.

Justin Israel

unread,
Mar 19, 2014, 8:52:16 PM3/19/14
to python_in...@googlegroups.com
@David, my implementation was a direct port of the example flowlayout.py from a QLayout -> QGraphicsLayout so that I could use it in a QGraphicsScene. I do all of my image result listing there instead of a QWidget system 


David Martinez

unread,
Mar 24, 2014, 10:51:44 AM3/24/14
to python_in...@googlegroups.com

I think that I'm getting rather confused when it comes to port the class.

 

As far as I know, when we deal with graphic elements we need both a 'Scene' (data) and a 'View' (what displays data). When we inherit from QGraphicsLayout, what we are creating is a 'Layout', right? Does that mean that the resulting class is going to be our view class?  Could you explain how the different elements relate to each other? This is the first time that I deal with graphic elements. All what I've done so far were regular widgets.

 

Many thanks



--
David Martinez - Technical Animator
 


Justin Israel

unread,
Mar 24, 2014, 2:48:19 PM3/24/14
to python_in...@googlegroups.com

Did you need to do a QGraphics approach or was this just an experiment after I mentioned I was doing it? Technically it will work as QWidget, but can end up being more performant as QGraphics if you use a ton of images.

Porting the flow layout is basically just converting it to be a subclass of QGraphicsLayout which has some slightly different concepts when it comes to the geometry. But it is the same in terms of what it functions as.
Layouts don't inherently have any visual representation. They just manage the size and position of the items assigned to it. So it wouldn't be considered a view. Just like in QWidgets, you still have to add the layout to the parent widget for which it will conform all the child widgets.
In a QGraphics setup, you have a QGraphicsView which looks into a QGraphicsScene (the model) to view all of the items. Layouts aren't actually part of the core concepts. They are something you can use if you are using QGraphicsWidgets, which support a mixture of graphics items a qwidget concepts.

David Martinez

unread,
Mar 25, 2014, 9:17:57 AM3/25/14
to python_in...@googlegroups.com
I think it's worth learning how to do it.

I need to be able to draw a few dozen images so I think the QGraphics approach is the appropriate one.
I do understand that layouts are not visual but define how elements are arranged. But how does work within a QGraphics approach?

As you mention, it looks like when working in a QGraphics setup, I need to have a scene (the model) and the view.
Does that mean that the layout will exist within the view? Or is it supposed to be part of a QGraphicsWidget?

With regular QWidgets, I can create a window to be that QWidget but that doesn't seem to be the case with QGraphicsWidget.

Finally, is the layout going to accept regular widgets and pixmaps or QGraphicsWidgets?


Sorry about the confusion but given how big the documentation is, I want to make sure that I'm looking at the correct elements to get the whole thing working.

Cheers


--
David Martinez - Technical Animator

Marcus Ottosson

unread,
Mar 25, 2014, 9:50:13 AM3/25/14
to python_in...@googlegroups.com
The traditional QLayouts aren't applicable to QGraphicsView, there might be alternatives, but more commonly you'd position items yourself, it isn't too tricky:

# Psuedo-code of a grid-layout
x, y = 0, 0
x_count = 3
spacing = 50

for item in items:
   item.move(x, y)

   x += spacing
   if x > (spacing * x_count):
      x = 0
      y += spacing



For more options, visit https://groups.google.com/d/optout.



--
Marcus Ottosson
konstr...@gmail.com

David Martinez

unread,
Mar 25, 2014, 10:51:23 AM3/25/14
to python_in...@googlegroups.com
True. I believe that's why Justin suggested to use a QGraphicsLayout (As it does not inherit from the regular QLayout) ?


--
David Martinez - Technical Animator
 


Marcus Ottosson

unread,
Mar 25, 2014, 11:32:31 AM3/25/14
to python_in...@googlegroups.com
Ah, did he, sorry I must have been out of date on following up on this thread. :) Carry on.



For more options, visit https://groups.google.com/d/optout.



--
Marcus Ottosson
konstr...@gmail.com

Justin Israel

unread,
Mar 25, 2014, 7:28:06 PM3/25/14
to python_in...@googlegroups.com
On Wed, Mar 26, 2014 at 2:17 AM, David Martinez <david.mar...@gmail.com> wrote:
I think it's worth learning how to do it.

I need to be able to draw a few dozen images so I think the QGraphics approach is the appropriate one.
I do understand that layouts are not visual but define how elements are arranged. But how does work within a QGraphics approach?

As you mention, it looks like when working in a QGraphics setup, I need to have a scene (the model) and the view.
Does that mean that the layout will exist within the view? Or is it supposed to be part of a QGraphicsWidget?

A view is just a QWidget that visualizes a certain area of a given QGraphicsScene. It provides the link of communicating user interactions to the scene and the items of the scene. It really has no intimate knowledge of the actual items in the scene. 

Just like a normal QLayout, you have to add a QGraphicsLayout to a parent item. In this case it would be any QGraphicsWidget. QGraphicsWidget is an extension to the QGraphicsItem, which adds support for layout and geometry and things like act more like QWidget. So if you want to work with QGraphicsLayouts, then you have to work with QGraphicsWidgets as the items being added to the layout. 

Then you just think of your parent QGraphicsWidget like a window. While your QMainWindow exists somewhere on your global screen space, your parent QGraphicsWidget will exists somewhere in the global scene space. 
 

With regular QWidgets, I can create a window to be that QWidget but that doesn't seem to be the case with QGraphicsWidget.

Finally, is the layout going to accept regular widgets and pixmaps or QGraphicsWidgets?

You would probably be working with QGraphicsItem subclasses, like QGraphicsPixmapItem 
While QGraphics does support a concept called "proxy widgets", which let you put normal QWidgets into a QGraphics scene, they should be avoided for performance reasons. That suggestion even comes from Qt core dev. It was put there as a convenience, but if you use it, then you are kind of making it pointless to really use QGraphics. 
 
Reply all
Reply to author
Forward
0 new messages