I've created a widget that uses the QGraphicsFramework to draw items to a canvas. Currently, I use one QGraphicsScene to keep track of my items and a QGraphicsView to visualize the items in the scene. I am using PyQt, but this is really more of a general Qt question.
This is what I have. It's one QGrapicsView and one QGraphicsScene.
What I want, where it's all drawn on one QGraphicsView, with three QGrapicsWidgets.
The first problem is that I don't know Qt that well so I am not sure if I understand the concepts correctly. It is my understanding that a QGraphicsWidget inherits from the QGraphicsItem so that I can add many of them to the same scene while still being able to handle all the events internally.
The problem with that is that the items inside each of these widgets need their own grid because items need to be at some given coordinates and have transforms inside the widget, etc. I am not sure how this could function, since there doesn't seem to be any such QGraphicsLayout that would allow this. This also kind of means each widget would need its own QGraphicsScene. I am not sure how to achieve this.
Can a QGraphicsWidget even have its own scene or does it have to access the shared main scene? If it had to access the shared scene, then each widget would need to be aware of where it was, which seems silly.
I don't need an implementation, just a clarification of how I would go about achieving this with QGraphicsWidgets. Or is my understanding of the QGraphicsWidget completely off?
Related
I'm building a program where a user can interact with a pyqtgraph ImageView (e.g. place markers, change brightness and contrast). I want to be able to cycle through different images, but have each image remember its state with the markers etc. I feel like the most appropriate solution would be to create a copy of the ImageView for each image and show the current one and hide the other ones. What would be the best way to do that and would that even be a good idea?
My naive approach was placing an empty widget in Qt Designer (called graphWidget), promoting that to the ImageView class, and then in the program:
graphWidget_backup = self.graphWidget
secondWidget = pg.ImageView()
secondWidget.setImage(np.random.rand(256,256))
self.graphWidget = secondWidget
But with that, nothing happens.
Of course I could also just save the image data and all other changes manually and set them on the ImageView, but that feels less elegant and "object oriented".
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.
What it is the best way to make a chessboard for checkers using Kivy framework?
I have board.png, white.png, black.png, white_q.png, black_q.png files already. I wonder how to assign to each black tile on my board.png its own coordinate. Should I create 32 transparent widgets placed on black tiles of board.png or it is impossible? And what widget to use for 24 checkers? Any ideas or it is too complicated using Kivy and I should use tkinter?
There are many ways you could do this. It isn't complicated, it's very easy. The best way depends more on how you want to structure your app than anything else.
I wonder how to assign to each black tile on my board.png its own coordinate
Set the pos attribute of a widget to control its position, or better in this case use a layout that does what you want. For instance, adding your squares to a GridLayout with the right number of columns will have the right effect without you needing to worry more about positioning them.
Should I create 32 transparent widgets placed on black tiles of board.png or it is impossible?
I don't understand what you're asking here. You can make transparent widgets if you want but I don't know why you'd want to.
And what widget to use for 24 checkers?
The real question is, what do you want the widget to do? e.g. if you want it to display an image then inherit from Image.
Overall this answer is very generic because your question is very generic. I suggest that if you're stuck, try to ask a more specific question about a task you're struggling with, and give a code example showing where you are now.
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.