I have a wxPython application which allows the users to select items from menus that then change what is visible on the screen. This often requires a recalculation of the layout of panels. I'd like to be able to call the layout of all the children of a panel (and the children of those children) in reverse order. That is, the items with no children have their Layout() function called first, then their parents, and so on.
Otherwise I have to keep all kinds of knowledge about the parents of panels in the codes. (i.e. how many parents will be affected by a change in this-or-that panel).
More in response to your comment to Jon Cage's answer, than to your
original question (which was perfectly answered by Jon):
The user might find it irritating, if the position of every element in
your dialog changes, when he makes a choice. Maybe it'll look better,
if only the "variable part" is updated. To achieve this, you could
make a panel for each set of additional controls. The minimum size of
each panel should be the minimum size of the largest of these
panels. Depending on the user's choice you can hide or show the
desired panel.
Alternatively, wxChoicebook might be what you need?
Have a look at wxSizers and some examples for a fluid way to layout forms.
You can specify heights, poportions etc. etc. and then let the layout code do the rest for you :)
Related
I'm building a PyQt5 widget that will show search results.
The widget is a scroll area that has a vertical layout set to it, each item in it is a "search result" widget.
I want to update the list of widgets for each search result by clearing all the "search result" widgets, make new instances of "search result" that match my search and display them.
In my googling journey most of the suggestions I've seen are of the following format:
Psuedo code:
while widgets in layout:
delete last item (by either setting parent to None, or calling deleteLater() )
All the proposed solutions I encountered share the same structure that doesn't seem optimal at all to me, wouldn't I get a more responsive result by deleting the layout and making a new one?
according to PyQt documentation, calling deleteLater() will also recursively schedule the children nodes for deletion when Qt.WA_DeleteOnClose attribute is set to True. I'm am still in very early stages of learning PyQt but I assume that using this will not block my code as opposed to looping through all the widgets in the layout.
And even if it's not so I can alternatively replace the current layout and take care of disposing the old one after I'm done initiating the new one.
to clarify a bit on my rambling, this is an example of a suggested approach that I saw:
for i in reversed(range(layout.count())):
layout.itemAt(i).widget().setParent(None)
And here is what I'm planning on using (where self is the scroll area widget):
self.layout.deleteLater()
self.layout = QVBoxLayout()
self.setLayout(self.layout)
This will leave me with more room to manage and schedule deleting the layout. Also I've read that neither setParent(None) or deleteLater() are ideal solutions in the sense that sometimes they present unexpected behavior like not actually clearing the widget references in the layout, so switching to a new instance of a layout should at least secure me consistency regarding that?
P.S. Is there a better performance wise (responsive, less memory/CPU usage) implementation that will not sacrifice the simplicity of the structure too much? My project is for a small lab inventory tracking, but if I ever have to scale it I feel like having thousands of search result widgets is not ideal. yes I could load x amount of results at a time, but other suggestions will be welcome :)
I've a Treeview widget, and I need only one row/item to be selected at a time. I've been reading the doc, but I can't find any property or method to do so, nor I've found something useful on SO.
Is it posible? How to?
The answer is a bit higher up the page:
selectmode
Controls how the built-in class bindings manage the selection. One of “extended”, “browse” or “none”. If set to “extended” (the default), multiple items may be selected. If “browse”, only a single item will be selected at a time. If “none”, the selection will not be changed.
Note that the application code and tag bindings can set the selection however they wish, regardless of the value of this option.
Setting selectmode="browse" should give the behavior you're asking for.
I have a splitter window with a list box on the left and a panel on the right. When I click on an item in the listbox, the panel changes to a panel that is specific to that item. Many of these panels look similar by design, and are all generated from the same class with settings taken from the item.
I would like to add some sort of feedback so the user can tell that something has changed. Something basic, like the panel switching to empty panel for a fraction of a second, and then switching to the new panel would suffice.
Do you have any suggestions on the best way to do this? Does wx have a feature that already handles this or something similar? Will I just have to do exactly what I outlined above, if so, if there a recommended time to display the blank panel? I could play around with timing to find what I feel is right, but I'm sure there has been studies into simple concepts like this. I may end up choosing a delay that is too quick and most users may miss it, but it may seem normal to me as I am the one testing it. I may prefer shorter delays so I can test more quickly, and my opinion will be biased.
How can I auto scroll for the scroll area? For example, when there is a new update instead of the view of the scroll area staying the same, I want to go down with the new text. Think of it as in a CMD console, when you type a command it autoscroll with the output.
I was just going to respond to the other answer, but I just didn't know the best way to phrase it in the space allotted.
QScrollArea's are very useful widgets to use when designing custom PyQt widgets - I use them often. Things like rollout widgets, card widgets, anything where you could be displaying multiple sub-widgets with the need for scrolling can be a very useful utility. I don't agree with the idea that a QScrollArea isn't much use on its own.
The QTextEdit answer solves the problem the developer was facing - but only because it so happens the question is really about that. If you're trying to scroll a text edit, go with that answer.
However, if you are searching for an answer to the actual question and come across this thread, then the way to scroll down a QScrollArea is by actually modifying the scrollbar's value.
area = QScrollArea(parent)
vbar = area.verticalScrollBar()
vbar.setValue(vbar.maximum())
If you want to scroll to particular areas or anything (like implementing the ensureCursorVisible) then you want to take the location on the area's widget that you want to scroll to, figure out the percentage of the height of it, and apply that value to the vertical scrollbar. (Pseudocode)
Use QTextEdit.moveCursor to set the location you want to scroll to, and then use QTextEdit.ensureCursorVisible to scroll to it:
textedit.moveCursor(QtGui.QTextCursor.End)
textedit.ensureCursorVisible()
I'm new to PySide and Qt at all, and now need to create an application which has a tree view with styled items. Each item needs two lines of text (different styles), and a button. Many items are supposed to be in the view, so I chose QTreeView over QTreeWidget. Now I managed to add simple text items (non-styled) to the QTreeView and have almost no idea about how to place several widgets on one item. Could you please give me an example of how to create such design?
I've found some samples on the Internet, that are similar to what I want, but they all are in C++, and it's not obvious how to convert delegates and other things to Python. I'm now really confused about it all...
I'd recomend you use simple QTreeWidget and insert complex widgets with setItemWidget. While Qt's widhets are alien, they are not so heavy to draw, but:
You shouldn't create delegates.
You shouldn't handle events (If you are going to place button in view and draw it using delegates, you had to handle all its events, such as mouseOver, focus changing, etc. It is a lot of work.