Efficient method for a grid of clickable images in wxPython? - python

Which is the most efficient method to display a grid of about 1000 clickable images in wxPython ?
Currently i am using a GridSizer filled with StaticBitmap objects. But its quite slow for 500+ images.
One more thing is that, i have a listbox of categories on the left. That is to filter the images. Categories will be like "All", "Cat 1", "Cat 2" etc. When i click "All", all the image have to be displayed.
How i am doing this currently :
A VERTICAL BoxSizer will contain n
GridSizer objects, one for each
category. I add the StaticBitmap
objects to multiple GridSizers
depending on the categories it
belongs to.
Then i display only that GridSizer
depending on which category is
selected
This method is also terribly slow for anything over 300 images. So, how do i achieve the same effect efficiently ?
.

I'm assuming that not all 1000 images are onscreen at the same time, correct? If so, you should be able to just load up the number you need and when the user scrolls, load up the next set as needed. I think the people on the wxPython list usually used DCs to blit their images onscreen or they use the FloatCanvas widget. I would recommend asking over on their list where there are a number of experts on drawing images onscreen: https://groups.google.com/forum/#!forum/wxpython-users

I would think a ListCtrl in ICON style would be the best way to do this.
If you look at the wxPython Demos, the UltimateListCtrl sample in the wx.LC_ICON style is a good example of what you could create.

Related

Is it possible to create visual elements in PyQt6?

As my code is quite long and with a lot of nested layouts I won't put it in here but I essentially have a QHBoxLayout which I want to have a different background colour as the others. I First thought about changing the stylesheet but I quickly learned that the layout is not affected by that as it apparently is not a visual element. Hence my Question: How do I create simple (geometric) elements? Is it even possible to just have a colored box in the background and some lables and pictures in the foreground?
I tried just using a big QTextEdit block and colouring this with the StyleSheet but this didn't get me the results I hoped for as It'd be hard to align the text the way I want it to be and add pictures.

How to make multiple Fonts in one string, python, tkinter

In Tkinter, I would like to have different fonts in one Label.
So, the practical case is this: I have a Text Widget and in the text widget there is a bunch of Labels, each containing three lines: Title, Duration - Channel, and Description.
I would like to make the Title stand out by making it bold. Can this be done? So far I didn't find information that helped me out, and in the past I encountered the issue and didn't manage to find a solution.
I would prefer not to have 3 labels, because I have nice borders around the label. It would really complicate things.
Of course, I don't mind a bit of complication if it is necesary, but if it is unnecesary, then that would be nice. It seems like it should be normal functionality, like some tags or so.
You can't use more than one font in a label. If you need multiple fonts you'll have to use a Canvas or a Text widget, or combine multiple labels inside a frame. Arguably, the simplest solution will be a three line text widget.

In wxpython, how to set position of objects within a wxScrolledWindow

I am writing a kicad plugin, and I need to create a GUI for this plugin. Because kicad uses wxpython, that is what I am using.
I have already figured out that placing my ui items using the layout sizers just isn't gonna give me the control I need to create the window I want. I know I can set the position of elements, and have been using that to create the ui I need.
The problem however, is that my window gets bigger than what would be reasonable (in some situations). Therefore I want to make it scrollable.
I have been playing around with wxformbuilder, and I found the wxScrolledWindow. That got me this far:
This is roughly what I want, except, when you want to place stuff within the scrolledWindow, you have to place one of the "sizers" in it (as far as I can tell at least), in which you place your buttons. The problem with that is, that, to my knowledge, setting the position of buttons in any of the sizers just has no effect at all.
So, my question is: how do I achieve this effect? and, is this even possible?
edit:
As an example of what I am trying to put within the scrolledwindow, this is a rough version of the ui I want to create (and want to be scrollable). (I want to eventually have, probably an icon button above each of the checkbox columns to indicate what they are for).
The final result would need to look something like this (the white squares being small images / buttons, also, in reality being not on the window bar,but in its own not scrolling section):
An example of something I wasn't able to achieve using sizers is, getting those checkboxes so close together, without making them appear off center. Different widgets seem to have different sizes, and checkboxes without border are especially small, so they end up appearing off center, example:
Also, those images above each column of checkboxes, which don't scroll, need to line up with the X coordinates of those scrolling checkboxes, which also seems very non trivial. Though also really hard to get right if I could give everything exact coords, so I might need to give up on that specific idea of making those not scrollable.

Qt: get all children within region of the parent

This is my first question ever so bear with me!
Currently in my program, I have a parent widget which acts as a canvas. The user can add or remove widgets to the parent at run-time. Those widgets are then given an absolute position, that is, they are not positioned by a layout. Once added, a widget can be moved around arbitrarily by the user.
I want the user to be able to select a group of widgets by dragging a box around them. I have already coded the part that displays the rectangle while the user is dragging. Now, I want to be able to retrieve all the widgets within that rectangle (region).
I am aware of the findChild() and findChildren() functions, and they indeed do return the children as they are supposed to. But what I'd really need is a way to limit the search to the boundaries of the region since there will most-likely be quite a lot of widgets within the 'canvas'. (There could be thousands of widgets spread over a very large area due to the nature of what I'm doing!)
Here is my question: What would be my best option? Should I just go ahead and use findChildren() and loop through the list to find the children within the region manually. Or should I loop through all the pixels within the region using findChild(x, y)? Or perhaps there is an even simpler solution that would speed up the process? Something along the lines of findChildren(x, y, width, height)?
Hopefully my question made sense. I tried to explain things as best as I could. Thanks!
If you had used QGraphicsScene instead of rolling your own, you could have used the items(..) methods to very efficiently find your children in a particular area.
It's only possible in QGraphicsScene because it uses a BSP spatial acceleration structure, so if you cannot migrate to QGraphicsScene in a reasonable amount of time - you are going to have write your own. It's not as hard as it sounds, I've written numerous bounding volume hierarchy structures and they're quite straightforward.

QGraphicsView with automatic items placing

I would like to write an asset browser using QGraphicsView. It's a little different from examples using QGraphicsView and QGraphicsItems, because I want only one scrollbar and I want items to move automatically, when the viewport size changes. For example, when viewport width is large enough to display 4 asssets, they should be displayed like this:
aaaa
aaaa
aa
but when viewport is shrinked and can only contain 3 in a row, it should display them like this:
aaa
aaa
aaa
a
I wouldn't like to have to move those asset's by myself and let the graphics view manage them all. Is it somehow possible?
I have written once such a thing, but using QWidget and paintEvent, drawing all assets myself and keeping track of how many assets can be displayed in a row. Can it be done simpler with QGraphicsView?
QGraphicsView supports layouts. What you have to do is implement your own layout manager, inheriting from QGraphicsLayout.
For the layout you require, take a look at the Flow Layout example of Qt. Converting that example will give you a QGraphicsFlowLayout. Add your QGraphicsItems to this layout and set your QGraphicsView's layout to that layout, and that would do the trick.
It sounds to me you want a list, not a graphics view. A list can be set to display things wrapping around like you desire. See the puzzle example, paying attention to the list of puzzle pieces on the left. It looks pretty simple to set up for the case presented.
Of course, if you really want it in a graphics view, I suppose you could add a list to the view and use it there.
I would use a custom layout to do this. Try to create your custom Layout class that inherits from QGraphicsLayout and manage the way it is placing items.

Categories