wxPython: how to lay one panel over another - python

This is about wxPython.
I would like to have 2 Panels laying one over the other:
PanelBG should be some sort of a "background", with its own GridBagSizer with subPanels, StaticTexts and so on;
PanelFG should be the "foreground" panel, also with its own GridBagSizer with some StaticTexts, Buttons... but a transparent background, in such a way that PanelBG is visible wherever PanelFG doesn't lay widgets.
I need both Panels to stretch to all the sides of the frame, even when resizing the window, though never changing the reciprocal proportions, that's why I'm not sure if there's a way to use absolute positioning.
In case you are wondering, the reason why I don't want to use a single Panel is that merging the 2 GridBoxSizers would require me to place many many more cells in the sizer, because rows and columns of foreground and background don't always coincide, and I should split them in many cells, with grid dimensions growing up to hundreds**2.
Since the content I want to put in the foreground needs to be updated and refreshed quite often, this would require redrawing all the cells every time, which would take 10 - 20 seconds to complete the operation (tested). Updating only the foreground would require just some hundredths of a second instead.
Thank you!

This would be at least partially a change of direction, but it might be worth examining what other rendering options you have.
In particular, I'm thinking of wxWebKit (http://wxwebkit.kosoftworks.com/), which would let you do layering, etc. using the WebKit browser rendering engine. I'm not sure whether it's at a stage that would provide everything you need since I haven't actually used it, but even if it doesn't work then it may be an approach worth trying - using HTML/CSS for part of your display, while wrapping the whole in a wxPython app.

As I understand it, this is a calendar with rectangles for the days containing the events for the days.
The simple thing would be to use a wxGrid, with seven columns and four or five rows, to represent the months. You would then place the events into the grid cell for the correct date. The wxGrid widget would look after the details of refreshing everything properly.
Using wxGrid you might lose a little control over the exact appearance, though wxGrid is very flexible and feature rich once you learn its many methods, but you would save yourself having to write large amounts of code that would require significant effort to debug.

Related

PyQT how to change layouts size

I am trying to make a GUI that is very similar to Spotify using PyQT
I've already designed the main window and I am struggling with applying the design to QT Creator.
This is what I want it to look like
But I'm trying to use Layouts in order to organize every widget.
For example
Image of the main window, split into 3 parts
like in the sketch I've made the software will be split into 3 parts, left bar, mid which is where the explore title is and right bar.
The problem I have is that I can't control the layouts size and the size of what's below them for example in the sketch the mid bar is wider than the right bar and the right bar is wider than the left bar but in the QTCreator I've no idea how to change the width and height of objects inside Layouts.
The first option (which I personally prefer) is to fill your layout with it's contents first (buttons, labels, etc.). This will already start to scale your layout, if there are more buttons in the middle bar than on the other bars. If your layout still isn't what you want it to be, you can use Spacers. They can push and pull puttons and position the in relation to other parts of the layout, as well as to the layout itself. The scaling will be adjusted automatically according to the spacers position.
This option has the advantage, that your application will be correctly scaled and not completely chaotic when it is run on a device with a display aspect ratio which is not the same as the one of the machine your developing it on.
There is, however, also a minimumSize and maximumSize attribute to the layouts, which provide a much more straightforward possibility, but sometimes cause your layouts to become very weird when adding or removing a button, or changing the text of a label. More on this option can be found in the Qt docs:
https://doc.qt.io/qt-5/qlayout.html

How can I limit the rendering done by QScrollArea?

I have a Widget that is huge (80,000 px long maybe? 800 elements at 100px each) because it lays out many smaller widgets. I've put the huge widget into a QScrollArea. But the scroll area still renders the entire widget. This causes manipulation of the widget to be choppy, and I want things to be smoother.
Instead I want the QScrollAea to be intelligent enough to only render the elements that I know will be displayed. (The elements are ordered and are all the same fixed size, so this computation should be fast)
What's the best approach to go about this? Should QScrollArea already be doing this?
Does QListView already implement this functionality? (But I want my own custom widget in there it has buttons that interact with the user, QListWiget doesn't cut it.)
Have you considered using a QGraphicsView? This allows scrolling in addition to efficient rendering of only the visible objects (and plenty of other benefits such as hit testing).

Right approach for speeding up presentation of large amount of data?

First question ever on stackoverflow. Been reading for some time now, while trying to learn Python and wxPython.
I'm writing a small app for presenting a large amount of data on the screen in a custom way. The data is stock information stored in objects in Python. Its about 100 stocks that should be presented at the same time on the screen. Every stockobject has 35 attributes, so it makes 3 500 attributes showing at the same time. And I want different fonts, size and colour depending on attribute. The background of each stockobject is changing depending on user (me) input.
So I tried making a interface with wxPython and a lot of StaticText controls. It took 5 seconds to load, timing it with timeit module.
Googling the net gave me an idea to draw the data on a device context instead. That took only 0.1 second. To make the app clickable I draw a second picture into memory with specific colours for each attribute. When clicking on the panel showing the picture I compare the coordinates with the DC in memory to calculating what was clicked. And now I am about to write a sizer routine so the user can change fontsize.
Well my question is quit simple: Do you think I chose the right approach?
Or is there a simpler more pythonic way to do this, without using StaticText that took forever to load?
Grids is not a solution for me, because I want the data to be presented in a very specific layout. To be able to do that with a grid, I would have to set the grid to 2px with and hight, and then merge cells all over the place...
edit:
link for downloading picture of the controll as it looked yesterday:
http://dl.dropbox.com/u/10606669/super.png
Ugly and not the exact way I want it to lok. This because of trying to write my own sizer routine.
You can try freezing the whole frame during the loading process, like this:
frame.Freeze()
try:
# load all data
finally:
frame.Thaw()
In general, though, having that many Window controls will hurt performance, so custom drawing is the only solution. You could simplify things a little by creating your own custom control for one stock (with its own EVT_PAINT handler, etc.) and then creating 100 of them. It should make your DC calculations easier. See Creating Custom Controls for more information.

Creating a Selection tool using PyGtk

Can anyone help or point me in the right direction for figuring out how to create a drag and draw rectangular box to be used as a selection tool in PyGtk? I am presently using an event box with a drawable window and the user can click once in the upper left and once in the lower right corner of the portion of image they would like to choose which will then draw a rectangle over the selection, but a drag and draw rectangle will allow the user to better adjust and get better accuracy.
I have looked quite a few places for information or a tutorial on this but I haven't found much. I am relatively new to Gtk+ so perhaps this is so simple that no one has to ask.
Actually, this doesn't seem all that lamebrained at all. It is actually quite specific, and a little challenging.
I'll give you the steps to start you off, but as you're beginning (and you didn't post any specific code), it would be better for you to create the code yourself based on documentation and my hints.
By the way, look up the official PyGTK documentation - that should be your definitive source for all the objects and functions of PyGTK. It is very well written and exhaustive, and I rarely have to look more than five minutes to find what I need.
What I suggest you do is use three signals, connected to your drawing area.
button-press-event
button-release-event
motion-notify-event
Create three callbacks (tutorial here), one for each event. Connect your drawing area to your events and callbacks (again, see tutorial. You may need to go through a few pages on it.).
You are going to also need to create two boolean variables on the global level (above the main class, at the same level you import modules.) The first controls whether the selection tool is chosen (call it "Select_On"), and the second for if it is active (call it "Select_Active")
On the button you use to start the select tool, set "Select_On" to "True". This should probably be a toggle button, so make sure you set it up so "Select_On" gets set to off if you toggle the button off.
On button-press-event, create the object for selecting. What you're going with now actually should work well. Also, set "Select_Active" to "True".
On motion-notify-event, change the size of your object based on cursor position. Refer to that documentation for that particular kind of object to learn how to change its size, and refer here for how to get the cursor position.
Be prepared to write an algorithm to determine how to change the size of the selection object based on the cursor position. If you need help with that, feel free to ask for it in a separate question.
On button-release-event, set "Select_Active" to "False", and call all your code for actually confirming the selection.
As an aside, the benefit to using the "motion-notify-event" is that, as soon as the cursor leaves the widget you're selection in, the selection box stops changes sizes. The cursor must re-enter the widget to continue changing the selection box size.
I hope all that works for you, and wishing you the very best on your project!

How do I overlap widgets with the Tkinter pack geometry manager?

I want to put a Canvas with an image in my window, and then I want to pack widgets on top of it, so the Canvas acts as a background.
Is it possible to have two states for the pack manager: one for one set of widgets and another for another set?
The answer to your specific question is no. You can't have two states or otherwise use pack two different ways in the same parent.
However, what I think you want to accomplish is simple. Use the built-in features of the canvas to create an image item that is part of the canvas, then pack things into the canvas as if it were a frame.
You can accomplish a similar thing by creating a label widget with an image, then pack your other widgets into the label.
One advantage to using a canvas is you can easily tile an image to fill the whole canvas with a repeating background image so as the window grows the image will continue to fill the window (of course you can just use a sufficiently large original image...)
I believe that Bryan's answer is probably the best general solution. However, you may also want to look at the place geometry manager. The place geometry manager lets you specify the exact size and position of the widget... which can get tedious quickly, but will get the job done.
... turned out to be unworkable because I wanted to add labels and more canvases to it, but I can't find any way to make their backgrounds transparent
If it is acceptable to load an additional extension, take a look at Tkzinc. From the web site,
Tkzinc (historically called Zinc) widget is very similar to the Tk Canvas in that they both support structured graphics. Like the Canvas, Tkzinc implements items used to display graphical entities. Those items can be manipulated and bindings can be associated with them to implement interaction behaviors. But unlike the Canvas, Tkzinc can structure the items in a hierarchy, has support for scaling and rotation, clipping can be set for sub-trees of the item hierarchy, supports muti-contour curves. It also provides advanced rendering with the help of OpenGL, such as color gradient, antialiasing, transparencies and a triangles item.
I'm currently using it on a tcl project and am quite pleased with the results. Extensions for tcl, perl, and python are available.
Not without swapping widget trees in and out, which I don't think can be done cleanly with Tk. Other toolkits can do this a little more elegantly.
COM/VB/MFC can do this with an ActiveX control - you can hide/show multiple ActiveX controls in the same region. Any of the containers will let you do this by changing the child around. If you're doing a windows-specific program you may be able to accomplish it this way.
QT will also let you do this in a similar manner.
GTK is slightly harder.

Categories

Resources