A picture is worth 1000 words, so here is what I am trying to achieve:
In words, I would like to add a column to a tree view in which I can draw vertical connecting lines between certain rows of the tree view. This should work both when the tree view is scrolled, as well as when children of a row are expanded or collapsed.
First question: Is it at all feasible to do this within a ttk.Treeview? Since a tree view brings along all the additional functionality that I need, specifically for everything to the right of the connections column, I would prefer making use of it.
If not possible completely within a ttk.Treeview, how could I keep a separate canvas widget to the left of the tree view in sync with the tree view (row height, scroll position, collapsed/expanded children)?
Finally, if even keeping a canvas in sync with a tree view is not feasible, do you have an alternative suggestion regarding widgets and layouts in order to achieve this. Are there examples of using a grid layout to mimic the functionality of a tree view (expandable children, resizable columns)?
Related
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
I want to make elements in row in one layout and a lot of layouts will be in GroupBox, it must be like this.
Result Interface
I try to release this
formLayout = QFormLayout()
for i in range(50):
formLayout.addRow(QLabel(i), QPushButton("Start"))
groupBox.setLayout(formLayout)
self.scrollArea.setWidget(groupBox)
self.scrollArea.setWidgetResizable(True)
Result from code
I know that i should make in grib layout, because i have a lot of elements, but how can I create a layout with layouts which everyone have 9 elements?
Just explain how it should be grouped , like this scrollArea->groupBox->formLayout.addrow(elements)
I don't need full code, him I can write myself.
The layout you're showing is not a form layout, it could be a grid layout, but it actually seems more like a QTableView (or QTableWidget) or even a QTreeView (if those small arrows on the left are used to expand elements). Using nested layouts in this case might not be a good solution, as each layout would be independent from the others, with the result that the widgets might not be properly aligned. This small arrows for expand element in that case a QTreeView with a QStandardItemModel or a QTreeWidget might help, then use setItemWidget() to add buttons. –
musicamante
When expanding an item at the bottom of a QTreeView, the view does not automatically scroll to show the newly-expanded items. I can fix this by detecting expansion and performing the scroll myself when appropriate.
However, I would instead like to allow the user to scroll the view farther than is currently allowed. Currently, if the tree is too tall to fit in the visible area, the view can be scrolled only until the bottom-most row comes into view.
I believe this should be doable by tricking the QTreeView's size calculation, but even after source diving I don't understand the interaction between QTreeView and its base QAbstractScrollArea well enough to know what to poke, or where to start poking.
If all else fails I may just add some dummy, non-editable rows to my data model.
you can add extra white space to the treeview by increasing its vertical scrollbar maximum value. Smth like this:
max = self.treeview.verticalScrollBar().maximum()
self.treeview.verticalScrollBar().setMaximum(max*2)
hope this helps, regards
What's the main difference between the Tkinter geometry managers grid and pack?
What do you use for your projects ?
If grid is better to align object, what the main purpose of pack?
grid is used to lay out widgets in a grid. Another answer says it "overlays a graph" which is a bit of a misnomer. It doesn't overlay anything, it merely arranges widgets along row and column boundaries. It is great for creating tables and other structured types of layouts.
pack lays things out along the sides of a box. It excels at doing layouts where everything is on a single row or in a single column (think rows of buttons in a toolbar or dialog box). It's also useful for very simple layouts such as a navigator on the left and a main work area on the right. It can be used to create very complex layouts but it gets tricky until you fully understand the packing algorithm.
You cannot use both grid and pack with widgets that have a common parent. Your app may work but it is much more likely to get into an infinite loop as each manager tries to layout the widgets, then the other notices the widgets change size and try to adjust, etc. etc.
The third manage is place. Place is great for doing either absolute positioning (ie: place widget at a given x/y) or relative (eg: place a widget on the right edge of some other widget).
While you cannot mix grid and pack within the same container (a container is typically a frame), you can use both grid and pack within a single application. This is very, very common since each has strengths and weaknesses. I use both on a regular basis.
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.