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.
Related
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.
I need to do the following: suppose I have a widget opening on a window (as QWidget). That widget includes some plot. I also have a second window (as QMainWindow) where I do stuff to that plot interactively: move it around and resize it. What I want is to create a third window that displays the exact same thing as the first window (the one with the plot) in real time. How could I go on doing this?
Why do I want this? The first window is going to be hidden and I want the third window so as to inspect that the correct thing is happening on the first one.
Cannot duplicate widgets. The closest thing is to create 2 widgets and in one of them you have to track the changes and apply them to the second (and vice versa). This task is not easy so I would recommend you only track some characteristics.
I have a python program where I have several matplotlib canvases embedded into a wxpython application. One of the canvases has many crosses in it. When the user right-click in this canvas the closest cross should be removed together with everything belonging to this cross (they are linked through an unique id-tag, and there might be things in every canvas that should be removed). I want the removing (or actually the replotting) to be as fast as possible. The program is quite large so I use several threads etc.
The easiest thing to implement this is to use wx.CallAfter(canvas.draw) for each canvas. However, there is a delay between the rightclick and the refresh of every canvas so I believe that canvas.draw() is too slow.
I saw two other functions for fast redrawing: the matplotlib functions blit() and draw_artist(). As far as I understand, blit() refreshes changed pixels inside some area (I used the axes bbox). I managed to get it to work with blit() in the sense that the program ran without crashing...but not updating what you see on the screen.
Did not manage to get draw_artist() to work when removing a pixel (tried using first line.remove(), then draw_artist(line) but the line was ofcourse already dead so draw_artist did not work).
Note: I called blit() and draw_artist() with wx.CallAfter()!
The feeling I have is that blit() is the best solution, but I did not manage to get it to update to the "screen-level". So my question is: what is the fastest and most resource-saving way of removing artists from matplotlib.canvases (embedded into wxPython) without redrawing more than you need to, but still let the change propagate to the screen?
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.
I have a gtk.IconView with several icons in it. Sometimes I will resize the window to see more icons. When I do this, the extra space generated isn't distributed evenly between all the columns. Instead, it all gets put on the right until there's enough space for a new column.
I'm not seeing anything in the documentation that would let me do this automatically. Do I need to check for resize signals and then manually set the column and row spacings? If so, which resize signal do I use.
Here's a picture of what I mean. I've marked the extra space in red.
This is what I'd like to see (of course, with the gaps actually evenly spaced, unlike my poor MS Paint job).
We have encountered that problem in Ubuntu Accomplishments Viewer, and as we managed to solve it, I'll present our solution.
The trick is to place the GtkIconView in a GtkScrolledWindow, and set it's hscrollbar_policy to "always". Then, a check-resize signal has to be used, to react when the user resizes the window (note that it must be checked if the size has changed, for the signal is emitted also when e.g. the window is dragged around). When the size changes, the model used by GtkIconView has to be cleared and recreated, as this triggers GtkIconView properly reallocating the newly gained space (or shrinking). Also, as the result the horizontal scrollbar will never be seen, as the GtkIconView uses exactly that much space as the GtkScrolledWindow uses.
Yeap, it seems after a very fat look that you will need to do that on your own. And regardeing the signal, I'd check for GtkContainer::check-resize.
Use the event size_allocate.
I defined my class :
class toto(Gtk.IconView):
def __init__(self):
super(toto,self).__init__()
self.connect("size_allocate",self.resize)
self.set_columns(4)
Then I modify the number of working columns
def resize(self,_iv,_rect):
print("X",rect.x)
print("Y",rect.y)
print("W",rect.width)
print("H",rect.height)
# calculate number of columns, let's say 3
_cols=3
self.set_columns(_cols)
Seems working for me