Reordering items in a QTreeWidget with Drag and Drop in PyQt - python

I have a QTreeWidget with what I thought all the proper settings setup in order to be able to reorder items by dragging them around. It can work, at times, but more often than not I drag an item into another one and it either disappears or becomes a child.
Is there anyway to prevent this from happening so you don't lose items you're trying to reorder? I figured you could achieve this within Qt Designer. I have dragDrop mode set to InternalMove and defaultDropAction set to MoveAction, but I'm not even certain of both of those are what I need to be adjusting.
Thanks in advance!

You can add flags to individual tree widget items that control drag and drop behaviour (amongst other things). For instance, to prevent an item being a drop target, try something like this:
item = QTreeWidgetItem(parent)
item.setFlags(items.flags() & ~Qt.ItemIsDropEnabled)
For more details, see: Qt.ItemFlags

Related

QToolbar.children() lists children in order of addition/insertion, not appearance

The QToolBar method insertWidget(QAction, QWidget) does correctly insert the widget at the intended place, but QToolBar.children() (actually QObject.children()) shows the output list of children ordered according to the order in which they were added or inserted, not in the order of their left-to-right appearance; the children() doc says that explicitly. That's probably not unreasonable, since children() is a method of QObject, and QObject knows nothing about its derived toolbar.
This may be related to a perplexing bug (IMO) in which QToolBar returns incorrect action objects on a mouse press event after an insertWidget(). I believe the system is counting the position of the clicked widget and returning its action object based on the (false) assumption that all widgets were added with addWidget(). But rather than dwell on this possible bug, my question is: is there a way to shuffle the output of children() such that it reflects the appearance of the widgets in the toolbar, rather than the order in which they were added or inserted? Brute force solutions are always possible, but I'd prefer something pythonic.
Edit:
(I think there used to be a link on this site, "answer your own question". I can't find it, so I'll post it here.)
It is not possible to shuffle the output of children() or its variants. However, a workaround is possible. The reason for wanting the toolbar items in order of appearance is so that they may be saved (e.g., in a ConfigParser file) and restored in the same order.
If any toolbar items have been added with insertWidget(), QToolbar.children() or its variants will not reflect the order of their appearance in the toolbar. IOW, code that looks like this is useless in finding widgets in toolbar order:
fieldlst = self.toolbar.findChildren(QPushButton,'', Qt.FindChildOption.FindDirectChildrenOnly)
However, a toolbar contains a layout which is implicity added and can be retrieved with QToolbar.layout(). Items can then be retrieved in the order of their appearance with code like this:
lt = self.toolbar.layout()
fieldlst = [lt.itemAt(k).widget() for k in range(lt.count())]
Cruder solutions are possible without using the layout, such as reading the enclosing rectangle of widgets returned by a children() variant, and then sorting on the coordinate of the left edge, but the solution given above seems simplest.

How to add a "remove button" at the right side of the hovering (or each) item of a wx.ComboBox popup

What I want is a mean to remove an item from the combobox without having to add a separate remove button somewhere else. So I want a remove button to appear at the right side on a combobox dropdown item when I hover over my mouse pointer on it. And, it is also OK if all the items have remove button at the right side and do not need hovering.
The images bellow will illustrate what I am saying [...please ignore my mspaint skils]
[combobox with remove button for hovering item]
https://i.imgur.com/kIMtF3G.jpg
[combobox with remove button for each item]
https://i.imgur.com/iyG23vG.jpg
[NOTE: Sorry, I cannot post images directly because it needs at least 10 reputation to post images.]
[I am new to python and wxpython. So please ignore my ignorance if any. And for the same reason any simple code sample will be greatly helpful.]
Regards.
The wx.ComboBox does not have this feature. The wxPython GUI toolkit uses the target platform's native widgets. If those widgets don't support doing it, then neither does wxPython.
However, wxPython does have custom widgets or you could create your own widget to do this sort of thing.
I also think you could use a context-menu for this task. You would need to right-click to make it work. Another method would be to bind to a mouse event and try to figure out where in the widget you are, but I think that method would be error prone.

Keeping track of an entry's index in Tkinter menus

I don't have a lot of GUI programming experience and very little in Tkinter, so bear with me. It seems to me that the Tkinter menu interface is seriously wrong. I'm referring in particular to the way menu entries are addressed.
Menu entries are not widgets. add_command - or, for that matter, any add - does not return an object which we can use to address the entry. In order to
reconfigure
delete
insert relative to
an entry, an index must be provided. The index is, usually, just an index in the current list of entries in the menu. That means, all entries that exist (after additions and deletions) at the present time in the index.
It seems logical to organize the code in a GUI around groups of functions that are related from a user's point of view. Say, Undo and Redo should be together in the Edit menu. But the Edit menu may also contain other groups of functions - Cut, Copy, Paste, or perhaps Find. It makes sense to put the code that handles Undo and Redo in one module, the code for Cut, Copy and Paste in another, the code for Find in yet another. These modules are unrelated to each other, except for the fact that they all exist in the Edit menu. However, just because of that fact, it seems that in Tkinter menus they need to know if a module "above" inserts or deletes an entry in its own "area", because that affects the indices of their own entries. Isn't that quite fragile? Or am I missing something?

Setting autoscroll in QTreeWidget

I am using QTreeWidget with single column. QTreeWidgetItem has multiple childs in some situations. I am updating dynamically, data in every QTreeWidgetItem. Now when I am adding this data to particular child & I am expanding it. But I am unable to set scroll to that particular QTreeWidgetItem.
Is it possible?
Thanx in advance.
Use scrollToItem. You can pass a scroll-hint as the second argument to control how the scrolling is done:
treewidget.scrollToItem(item, QtGui.QAbstractItemView.PositionAtCenter)

Gtk.Treeview deselect row via signals and code

I'm using PyGObject but I think this is a question that could be adapted to all GTK, so if someone know how to do it using C or anything should work in python also.
I have two treeview, Active and Inactive, I load data from a Sqlite database and I can swap and drag & drop items from one to other.
This is just an aestetic thing, if I click on one item on one treeview I want that a previous selected item on the other be deselected.
It appears that nobody had to do something similar because I didn't found anything about it on the net.
At the risk of being too basic (perhaps I misunderstand the problem), to manipulate treeview selections, you use the GtkTreeSelection object returned from GtkTreeView.get_selection. You can attach to signals on this object, change the current selection,etc.
To turn off selection in the other view, you can get its selection mode property and set to GTK_SELECTION_NONE. To turn it back on upon clicking, my thought was that you could catch a grab-focus signal, set the selection mode to single in that view, and set the selection mode to none in the other view:
(connect view-1 'grab-focus
(lambda args
(set-mode (gtk-tree-view-get-selection view-1) "GTK_SELECTION_SINGLE")
(set-mode (gtk-tree-view-get-selection view-2) "GTK_SELECTION_NONE")))
(That code is using the guile-gnome wrapper but the concept should be the same in any language binding.) A problem with this approach is that now in order to make a selection you must click the tree view twice - once to grab the focus, and again to make the selection.

Categories

Resources