Set Focus on QListWidget item when QStackWidget page chaged pyqt - pyqt

maybe a trivial question, sorry in advanced but I'm definitely not an expert.
I have an UI create with Qt Designer with a QListWidget (5 rows) and a QStackWidget (5 items). I'm able to change the QStackWidget pages when changing one of the QListWidget row with currentRowChanged(int) signal of QListWidget and setCurrentIndex(int) slot of QStackedWidget.
Is there a way to create also the same signal - slot when a page of QStackWidget chages so that the related row of QListWidget will be highligted?
I tried with signal currentChanged(int) and slot setFocus() but nothing happens.
Thanks for any suggestion

Related

Get the contents of a widget in a layout in PyQt

I recently decided to create a small application that simply reads the files in a compressed file and renames them. I went through several UI modules and decided to use PyQt6.
To achieve this, I first created a QWidget that holds the widgets QPushButton and QLineEdit.
The user then types the new name into the QLineEdit widget and select the QPushButton if the file has to be excluded.
Now, this widget that was created will be added into a QVBoxLayout which is then set as the QScrollArea layout.
Here's my problem:
Once I was done creating the scroll area and the list, I wanted to retrieve the content of each widget. For this purpose, I use the findChild method. But it only returns the address of the object.
Is there any way to get the text stored in QLineEdit of each widget? Is it possible to retrieve the text just by knowing its address?
Here's what I tried:
for index in range(self.layout.count()):
widget = self.layout.itemAt(index).widget()
nameFromLineEdit = widget.findChild(QLineEdit).text()
print(nameFromLineEdit)

In Python3/tkinter is there a way to temporarily stop accepting clicks in a Treeview widget?

I have a GUI based in Python 3 and tkinter that has a big ttk.Treeview. I have defined methods for row selection (one click) and opening an advanced info panel (double-click). I need to ensure that, after being double-clicked, for the next one or two seconds, the Treeview state won't be changed by another click. Is it possible to deactivate Treeview mouse bindings, like what we do with buttons?
Doing a little more research, I was able to come up with a solution for this. I just created an empty method that is called when the tree widget is supposed to be inactive. So, we can use something like this to "unbind" all the mouse events and re-bind them a few seconds later, as needed:
def nothing(self, *event):
""" # Hacking moment: A function that does nothing, for those times you need it...
"""
pass
def bind_tree(self):
""" # Bind mouse and keyboard events to their respective functions or methods...
"""
self.tree.bind('<<TreeviewSelect>>', self.selectItem_popup)
self.tree.bind('<Double-1>', self.show_details)
self.tree.bind("<Button-2>", self.popupMenu)
self.tree.bind("<Button-3>", self.popupMenu)
def unbind_tree(self):
""" # Unbind all mouse and keyboard events, by binding them to an empty method...
"""
self.tree.bind('<<TreeviewSelect>>', self.nothing)
self.tree.bind('<Double-1>', self.nothing)
self.tree.bind("<Button-2>", self.nothing)
self.tree.bind("<Button-3>", self.nothing)
Then, in the rest of the code, We only need to call bind_tree() and unbind_tree() as needed.
This worked for me:
tree.bind("<ButtonRelease-1>", my_select_function)
# Do some stuff
tree.unbind("<ButtonRelease-1>")

Create a signal for each item in QListWidget

I want to create a list of items using QListWidget and set it up so each time I click (select) an item a different method is executed. The way I thought about going about solving this is by connecting the list to a method that will check for the index and depending on the item index it will generate a signal connected to a different method. Thing is, I don't know how to generate this signal if I don't have a button or anything. The method is just checking for item index.
Any suggestions will be much appreciated!
The straightforward idea would be to connect the itemClicked signal to a slot in which a method is called depending on the clicked index. In this case you don't need a signal for every item.
But if you really want to create a "clicked" signal for each item and connect it to its respective slot(s), you could do it like this:
Subclass the QListWidgetItem and add a clicked signal to it. How to add custom signals
While filling the QListWidget, connect each item with its slots depending on its index.
Connect the itemClicked signal of the QListWidget to a slot, that emits the clicked item's signal like this:
def itemClickedSlot(item):
item.clicked.emit()

Listbox :How to display child dialog based on list box selection?

I am developing mfc based vc++ dialog application. In my program I have a one parent dialog say IDD_PARENT and two child dialogs say IDD_PAGE1 and IDD_PAGE2. In IDD_PARENT dialog i have a listbox control with the strings Page 1 and Page 2. When a user clicks Page 1 in list box I need my application to display the dialog IDD_PAGE1 in the IDD_PARENT dialog same for the case with Page 2 also. How can I do it? I am new to the VC++ environment. Examples using code portions will be helping.
Thanks to all
From your description, it sounds like you want embedded child dialogs. Have a look here.

Getting pyqt application focus for popup menu to disappear when clicking away from it

Let me quickly explain the background to this. I'm developing a custom menu system inside a 3D application called Softimage XSI. It has a PyQt application object created already and ProcessEvents is being called a certain number of times every second so that PyQt applications can exist in a non-modal state within XSI.
To implement the menu, I've got a webpage embedded in a toolbar which is calling a plugin for XSI that I've written to show a PyQt menu. This all works fine (albeit, slightly contrived!).
The issue is that when I show the menu, it won't disappear when I click away from it. If I move the mouse over the menu, and then click away from it, it will disappear. It's only when it first pops up.
I've tried everything I can think of. Here's a list:
Using QtGui.qApp.installEventFilter(menu) to try and catch the mousepressed signal. It never gets triggered. I suspect the application itself isn't receiving the click.
Using menu.raise_() makes no difference
Neither does QtGui.qApp.setActiveWindow(menu)
Or menu.setFocus()
I've also tried:
event = QtGui.QMouseEvent(QtCore.QEvent.MouseMove, pos, QtCore.Qt.NoButton, QtCore.Qt.NoButton, QtCore.Qt.NoModifier)
QtGui.qApp.sendEvent(menu, event)
I had a go writing my own QEventLoop, but it just crashed XSI. I suspect trying to run a modal loop inside the other one probably isn't a legal thing to do. Either that, or I really don't know what I'm doing (equally probable)
The only thing I have partial success with is using grabMouse(). This is what makes the menu close if I click away from the menu (only after the mouse has passed over the menu once), but I have to call it a couple of times for it to "stick".
So this is my code at the moment:
class MyMenu (QtGui.QMenu):
def __init__(self, parent = None):
QtGui.QMenu.__init__(self, parent)
self.grabbed=2
def getMouse(self):
if self.grabbed>0:
self.grabMouse()
self.grabbed-=1
def paintEvent(self, event):
QtGui.QMenu.paintEvent(self, event)
self.getMouse()
def hideEvent(self, event):
self.releaseMouse()
def ShowMenu():
menu = MyMenu()
menu.addAction("A")
menu.addAction("B")
menu.addAction("C")
submenu = MyMenu()
submenu.addAction("D")
submenu.addAction("E")
submenu.addAction("F")
menu.addMenu(submenu)
menu.setTearOffEnabled(True)
menu.setStyleSheet("font: 8pt \"Sans Serif\";")
submenu.setStyleSheet("font: 8pt \"Sans Serif\";")
submenu.setTitle("Window")
submenu.setTearOffEnabled(True)
pos = QtGui.QCursor.pos()
pos.setX(105)
menu.popup(pos)
#Prevent garbage collection
QtGui.XSIMenu=menu
QtGui.XSISubMenu=submenu
#Desperate acts!
menu.raise_()
QtGui.qApp.setActiveWindow(menu)
menu.setFocus()
Any thoughts or random suggestions would be very gratefully received as this is driving me nuts! Don't be afraid to suggest modifications to stuff I've already tried, as I'm relatively new to PyQt and I may well have missed something.
Many thanks,
Andy
Just before calling popup with self.trayMenu.popup(QtGui.QCursor.pos()), call self.trayMenu.activateWindow(). Putting activateWindow before popup makes the left-click menu work the same as the right-click menu and it goes away when you click elsewhere. :)

Resources