How to find QButton created with a loop? - python

in maya one creates a button with:
cmds.button('buttonname', label='click me')
where buttonname is the name of
the button object. At a later stage i can edit the button simply by calling:
cmds.button('buttonname', e=1, label='click me again')
Now the problem:
i created a bunch of buttons in qt using a loop:
for s in Collection:
file = os.path.splitext(s)[0]
# Main widget
widgetItem = QtWidgets.QWidget()
layoutItem = QtWidgets.QVBoxLayout()
widgetItem.setLayout(layoutItem)
# Button
button = QtGui.QPushButton()
button.setObjectName(file)
layoutItem.addWidget(button)
How can i call/edit one of them using the button name?
Thanks in advance

Assuming you already have access to their parent widget, you can find them by findChild method.
In C++ syntax, it would be something like this:
QPushButton *button = parentWidget->findChild<QPushButton *>("button1");
where button1 is the name of that button.

Related

How to access a widget in another widget event handler : Tkinter

I am creating a GUI in tkinter having a listbox and a Text item in a child window which appears after a button click. Listbox is displaying values of a dict which are basically names of files/directories in disk image.
I want to change the text of Text widget on <ListboxSelect> event and display type or path of selected file.
Now I cant make Text global since it has to appear on child window, so I need a way to access it in event handler of Listbox. Can I give handler reference of Textbox?
Here is my code;
def command(event):
... #Need to change the Text here, how to access it?
def display_info(dict,filename):
child_w = Tk()
listbox = Listbox(child_w)
textview = Text(child_w)
...
listbox.bind(<ListboxSelect>,command)
def upload_file():
window = Tk()
upl_button = Button(command=upload_file)
window.mainloop()
Is there a way to create a textview as global and then change its properties later to be displayed in child_window etc.
Two solutions here that I can think of is to make textview a globalized variable or to pass textview to command() as an argument.
Parameter solution:
def command(event,txtbox):
txtbox.delete(...)
def display_info(dict,filename):
child_w = Tk()
listbox = Listbox(child_w)
textview = Text(child_w)
...
listbox.bind('<ListboxSelect>',lambda event: command(event,textview))
Or simply just globalize it:
def command(event):
textview.delete(...)
def display_info(dict,filename):
global textview
child_w = Tk()
listbox = Listbox(child_w)
textview = Text(child_w)
...
listbox.bind('<ListboxSelect>',command)
While saying all this, it is good to keep in mind that creating more than one instance of Tk is almost never a good idea. Read: Why are multiple instances of Tk discouraged?

IPython nbwidgets: Toggle Visiblity by button click

I'm using the ToggleButton and want to link it's value to the visilbiity of another widget.
I've come accross the Widget Events, but it is unclear to me how to bind the style property of the other widget to the value of the ToggleButton.
Has anyone done something similar?
I would use an observe call on the ToggleButton to change the visibility of the other widget. A simple example below.
toggle = ipyw.ToggleButton(description='Toggle visible')
to_hide = ipyw.IntRangeSlider(description = 'hide me')
display(to_hide)
display(toggle)
def hide_slider(widg):
if widg['new']:
to_hide.layout.display = 'none'
else:
to_hide.layout.display = ''
toggle.observe(hide_slider, names=['value'])

Wizard-like user interface with buttons next and back

I'm developing an application using the Qt Designer and PyQt4, I need to make several screens where each screen I capture user-specific data, for that I need to implement a next button and a back button similar to
where the current screen closes and the following opens when the user clicks next or if he clicks back, the screen closes and opens the previous screen, I made an example with only the next buttons and back to exemplify, if I was not clear:
from PyQt4.QtGui import *
from PyQt4.QtCore import *
class Frm(QWidget):
def __init__(self, parent = None):
super(Frm, self).__init__(parent)
next = QPushButton('Next >', self)
back = QPushButton('< Back', self)
hbox = QHBoxLayout()
hbox.addWidget(back)
hbox.addWidget(next)
self.setLayout(hbox)
if __name__ == '__main__':
import sys
root = QApplication(sys.argv)
app = Frm(None)
app.show()
root.exec_()
In short: How do I implement a function that calls another screen and close the current at the click of a button?
First about a misconception: you do usually not create/show one screen (window) and close another, you usually only exchange the content of a wizard-like dialog window upon actions like pressing the buttons. The window is alive the whole time until the multiple page task is finished.
So I take it your question is really about:
How to exchange a widget in a layout?
Since you may still use PyQt4 which does not yet have QLayout.replaceWidget, it's best to just use methods removeWidget and addWidget of QLayout and since addWidget adds a widget to the end of the layout items list, I prefer a dedicated layout just for the interchangeable content of your wizard (see also: How to add an Item to the specific index in the layout).
Example code using PyQt5 but easily transferrable to PyQt4. Only the next button is implemented.
from PyQt5 import QtWidgets
class MyWizard(QtWidgets.QWidget):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
# vertical layout, wraps content layout and buttons layout
vertical_layout = QtWidgets.QVBoxLayout()
self.setLayout(vertical_layout)
# content widget and layout
self.content_layout = QtWidgets.QVBoxLayout() # could be almost any layout actually
self.content = QtWidgets.QLabel('Page1') # customize with your content
self.content_layout.addWidget(self.content)
vertical_layout.addLayout(self.content_layout)
# back, forward buttons wraped in horizontal layout
button_layout = QtWidgets.QHBoxLayout()
button_layout.addStretch()
back_button = QtWidgets.QPushButton('Back')
back_button.clicked.connect(self.back_button_clicked)
button_layout.addWidget(back_button)
forward_button = QtWidgets.QPushButton('Forward')
forward_button.clicked.connect(self.forward_button_clicked)
button_layout.addWidget(forward_button)
vertical_layout.addLayout(button_layout)
def back_button_clicked(self):
"""
The back button is clicked.
"""
pass
def forward_button_clicked(self):
"""
The forward button is clicked.
"""
# remove old content
self.content_layout.removeWidget(self.content)
self.content.deleteLater()
# create new content
self.content = QtWidgets.QLabel('Another Page')
# add new content
self.content_layout.addWidget(self.content)
app = QtWidgets.QApplication([])
wizard = MyWizard()
wizard.setWindowTitle('MyWizard Example')
wizard.setFixedSize(600, 400)
wizard.show()
app.exec_()
And it looks like:
However, as already written in the comment by Marius, there is quite extensive support for such dialogs in Qt using QWizard. So I strongly recommend to use that instead. The example above is only to demonstrate the ability of inserting and removing widgets in layouts.
You should definitely use QWizard for such problems!
There is a QWizard class that allows you to create wizards in Qt and PyQt. It implements all the functionality you want, and lots more. All you do is design your pages by extending QWizardPage, and add them to the wizard. This is much simpler than doing the whole thing from scratch as you propose.
Old question but missing example with existing API
You don't need to create all structure of an Wizard by yourself. Qt (and PyQt) already provides a class called QWizard.
Basic example:
wizard = QtWidgets.QWizard()
page1 = QtWidgets.QWizardPage()
page1.setTitle('Page 1 is best!')
page1.setSubTitle('1111111111')
lineEdit = QtWidgets.QLineEdit()
hLayout1 = QtWidgets.QHBoxLayout(page1)
hLayout1.addWidget(lineEdit)
wizard.addPage(page1)
Complete example and some explanation:
https://www.youtube.com/watch?v=kTJ1QULxXjg
https://impatientprogrammer.net/2018/07/06/pyside-pyqt-qwizard-in-3-minutes/

How to disable specific button in Pmw.ButtonBox?

I have added a button as:
def addButtons(self):
self.buttonBox = Pmw.ButtonBox(self.dataFrame,
labelpos = 'nw',
label_text = '',
frame_borderwidth = 1,
frame_relief = 'groove')
self.buttonBox.pack()
self.buttonBox.place(relx=.75, rely=.750, anchor=W)
# Add some buttons to the ButtonBox.
self.buttonBox.add('Login', command = self.login)
# Set the default button (the one executed when <Return> is hit).
self.buttonBox.setdefault('Login')
self.dataFrame.bind('<Return>', self._processReturnKey)
self.dataFrame.focus_set()
Now, I want to disable login button when user press it. How can i do that? I have found answer for simple button, but this button is in button box.
According to the pmw.ButtonBox documentation, the add method returns a reference to the button that is created. So, just save the reference that it returns and then configure that button like you would any other button.

How to update a Tix.ComboBox's text?

I have a Tix.ComboBox with an editable text field. How do I force the variable holding the value for the text to update?
Let me give a more concrete explanation. I have a combo box and a button. When I click the button, it pops up a message box with the value of the combo box. Let's say the combo box text field currently has the value "thing1". If I type "new" into the box and then click on the button with my mouse, it will pops up the message "thing1". If I type "new" in the box and then tab focus away from the combo box and then click the button the pop up message says "new".
Ho do I force the combo box to update it's value to new without requiring that I tab away from the combo box?
I have included sample code.
import Tix
import tkMessageBox
class App(object):
def __init__(self, window):
window.winfo_toplevel().wm_title("test")
self.window = window
self.combo = Tix.ComboBox(window)
self.combo.insert(Tix.END, 'thing1')
self.combo.insert(Tix.END, 'thing2')
self.combo.entry['state'] = "normal"
self.combo['editable'] = True
self.combo.pack()
button = Tix.Button(window)
button['text'] = "Go"
button['command'] = self.go
button.pack()
def go(self):
tkMessageBox.showinfo('info', self.combo['value'])
if __name__ == '__main__':
root = Tix.Tk()
App(root)
root.mainloop()
woo!
solved it on my own.
Use
self.combo['selection']
instead of
self.combo['value']
NOTE: copy of Moe's answer that can be selected as chosen answer
woo!
solved it on my own.
Use
self.combo['selection']
instead of
self.combo['value']

Categories