ipywidgets use checkbox to display or hide other widgets - python

I am using ipywidgets to create a short form, showing two fields, the expected width and the height of an image.
I want to add a checkbox so that if the box is checked, the information is loaded from a file instead.
If the box is checked, a text area (or file selector) should appear and a button to load the file read it and fill the text boxes.
Should I do this by observing the checkbox event? is there a way to hide a widget?

I'm not sure there is a hide function for a widget. One way to do this would be to construct an VBox for your widgets, and add the widgets as children. Then create a function/method which reassigns the children of that VBox to which ever widgets you want to show.
from ipywidgets import Checkbox, VBox
cb1 = Checkbox(description='1')
cb2 = Checkbox(description='2')
cb3 = Checkbox(description='3')
vb = VBox(children = [cb1, cb2, cb3])
top_toggle = Checkbox(description='Remove 3')
def remove_3(button):
if button['new']:
vb.children = [cb1, cb2]
else:
vb.children = [cb1, cb2, cb3]
top_toggle.observe(remove_3, names='value')
display(top_toggle)
display(vb)

Related

Add dynamic number of QLabel and QLineEdit inside a tab widget

I want to make a button that when press, it will generate a label and line edit. I tried using this code but the label will goes to the mainwindow. I want to put that on tabwidget page I create on QT designer.
def predict_student(self):
self.label = QLabel('This is label', self)
self.label.show()
I just solved my problem by creating a form layout inside the page and adding the label on that specific layout.
def predict_student(self):
self.label1 = QLabel('This is label', self)
self.formLayout.addWidget(self.label1)
self.label1.show()

Tkinter active fill by tag

I'm designing a GUI application using Tkinter and for this project, I need buttons for the menu. While looking into the buttons I wasn't blown away by the customization options that come with the buttons, especially when I found out that you can bind click arguments to rectangles.
This allows me to customize the "button" in (almost) limitless ways, but to allow me to put text on the button I need to create a rectangle element and a text element and bind them together using Tkinter's tag_bind property.
One of the design properties of the button that I wanted was active fill when the user moused over the element. Right now I'm just using activefill="" which works, except the text element and the button element will only fill while the mouse is over that element. So, for example, when I mouse over the button the button excluding the text will highlight and vise versa when I mouse over the text.
Below is a simplified (for brevity) version of what I use to generate the buttons;
button = canvas.create_rectangle(button_width, button_height, 10, 10, fill="000", activefill="111", tags="test")
text = canvas.create_text((button_width/2), (button_height/2), activefill="111", tags="test")
canvas.tag_bind("test", "<Button-1>", "foo")
Is there a way to bind the active fill function to a tag rather than a specific element?
Another option is that I completely missed a bunch of information about customizing the buttons in Tkinter, and I would not be apposed to learning about that.
Option 1
I would personally not go for the presented solution. I do not know if you are using the button provided by tk or ttk. But, with the tkinter.tk, you could absolutely change the appearance of the button.
Following, I give you an example that produces a button with the following characteristics:
Blue foreground
Flat appearance
When hovered, the background is green
When pressed, the background is red
The code is as follows:
import tkinter as tk
root = tk.Tk()
# Function hovering
def on_enter(e):
btn['background'] = 'green'
def on_leave(e):
btn['background'] = 'white'
# Create the button
btn = tk.Button(root, background='white', activebackground='red', foreground='blue',relief='flat',text='Test',width=20)
btn.pack()
# Bindings
btn.bind("<Enter>", on_enter)
btn.bind("<Leave>", on_leave)
# Loop
root.mainloop()
Option 2
If even after having tried the tk.Button, you are not glad with the result, I would create a Frame containing a Label (you can do nearly anything with that combination). Then, you could change the background of the frame according to any user action, like:
import tkinter as tk
root = tk.Tk()
# Function hovering
def on_enter(e):
lab['background'] = 'green'
def on_leave(e):
lab['background'] = 'white'
# Click
def on_click(e):
print("hi")
# Create the frame with a label inside
fr = tk.Frame(root)
lab = tk.Label(fr, text="Test", width=20, background="white")
# Packing
fr.pack()
lab.pack()
# Bindings
fr.bind("<Enter>", on_enter)
fr.bind("<Leave>", on_leave)
lab.bind("<Button-1>", on_click)
# Loop
root.mainloop()
You could even create a class with the above combination.

In tkinter, is it possible to place the same widget into multiple frames?

I have a UI with ttk.Notebook tabs, and would like to display the same widget in multiple tabs. This requires the widget to simultaneously have multiple parent frames, which doesn't seem possible. Is there some other way it can be done?
No, you cannot have a single widget in multiple places. A widget can only be in one place at a time.
I have since tinkered around with this problem, and have come up with this preliminary (and largely untested) solution to having a widget appear on multiple tabs of a ttk.Notebook.
Although the physical parent of a widget is immutably set when the widget is created, its geometric parent (which controls where it appears) CAN be changed using the .grid() in_ option. So in theory it should be possible to have the widget appear on multiple notebook tabs simply by changing its geometric parent whenever the user changes to a new tab (NotebookTabChanged)
The following code seems to work as advertised, although I haven't really tested it outside the toy code below:
import tkinter as tk
import tkinter.ttk as ttk
class myApp(tk.Tk):
def __init__(self):
super().__init__()
# Create the Notebook and bind the tab-select event
self.notebook = ttk.Notebook(self, width=500, height=200)
self.notebook.grid()
self.notebook.bind("<<NotebookTabChanged>>", self.select_tab)
# Create a status bar which displays the name of the currently selected tab
self.status = ttk.Label(self)
self.status.grid(sticky='w')
# Create three frames - one for each of three tabs - and store them in
# a dictionary with the tab names as keys
self.tabs = dict()
self.tabs['PAGE 1'] = ttk.Frame(self.notebook)
self.tabs['PAGE 2'] = ttk.Frame(self.notebook)
self.tabs['PAGE 3'] = ttk.Frame(self.notebook)
# Create the tabs in the notebook
for t in self.tabs.keys():
self.notebook.add(self.tabs[t], text=t, underline=0, sticky='nsew')
# Put a widget on the middle tab, just to have soemthing there
ttk.Label(self.tabs['PAGE 2'],text="A SIMPLE LABEL").grid(row=0,column=0)
# Create a button - this is the widget we wish to appear on all tabs
self.btn = tk.Button(self,text='PRESS ME!',command=self.button_pressed)
# This is the method called when the user selectes a new tab. It
# updates the status bar and moves the button to the new tab.
def select_tab(self, event):
id = self.notebook.select()
name = self.notebook.tab(id, "text")
text = f"--- {name} is currently selected ---"
self.status.config(text=text)
self.btn.grid(row=4,column=0,in_= self.tabs[name])
def button_pressed(self):
print('BUTTON PRESSED')
if __name__ == "__main__":
app = myApp()
app.mainloop()
Yes you can, example using two notebook tabs(aba1, aba2)
def widgets_with_icon(self):
aba=''
abas = (self.aba1, self.aba2)
for aba in abas:
self.tkimage3 = PhotoImage(file="images/salvar_100.png")
self.bt_image_save = tk.Button(aba, image=self.tkimage3, compound=tk.LEFT, bd=0, bg='#A9A9A9', activebackground='#A9A9A9', command=your_command)
self.bt_image_save.image = self.tkimage3 # reference to image not garbage collect
self.bt_image_save.place(relx=0.01, rely=0.01, relwidth=0.03, relheight=0.04)
self.bt_image_save (button with image only) will appear in aba1 and aba2.
I hope it can help.

PyQt4 Toolbar Button Alignment

I have this code
Menu = self.menuBar()
EditMenu = Menu.addMenu("&File")
OptionMenu = Menu.addMenu("&Options")
HelpMenu = Menu.addMenu("&Help")
EditMenu.addActions((fileNewAction,faultAction,storeAction,localAction,scheduleAction))
OptionMenu.addAction(settingAction)
Toolbar = QtGui.QToolBar()
Toolbar.setIconSize(QtCore.QSize(50,50))
Toolbar.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon|QtCore.Qt.AlignLeading) #<= Toolbuttonstyle
self.addToolBar(QtCore.Qt.LeftToolBarArea,Toolbar)
Toolbar.addActions((fileNewAction,faultAction,scheduleAction,storeAction,localAction,settingAction))
settings = QtCore.QSettings()
self.restoreGeometry(settings.value("Geometry").toByteArray())
which give me this
i used
Toolbar.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon|QtCore.Qt.AlignLeading)
to display the text on the right side of the toolbar button and to align all the toolbar button images to the left. But the texts are not appearing on the right side.
If i remove the QtCore.Qt.AlignLeading,
I get unaligned (left side) buttons like this
(1) How do i get my toolbar button icons align to the left and display the text on the right side at the same time?
Another question is
(2) How do i adjust the width of the raised button effect when i mouse over on each button? I want the width of all the buttons to be the same. The width seems to be different depending on how long the text is.
IMHO, the problem is the QToolBar decides on a size of each button individually, disregarding neighboring buttons completely. But you can set the size manually:
for action in my_toolbar.actions():
widget = my_toolbar.widgetForAction(action)
widget.setFixedSize(width, height)

Adding Content to pyqt4 scroll area

How can I add content to a scroll area in pyqt4? DO i custom define a widget? For example,
if i had a array or a lista =[10,2,2,2,22,3,3,3]. How should I display teh variable in the scrollbar area?
If you want to add content to a scroll area, you need to define a new widget and add that to the scroll area - like you would add a widget to a frame. For example:
textEdit = QtGui.QTextEdit()
scrollArea = QtGui.QScrollArea(MainWindow)
scrollArea.setWidget(textEdit)
Then, you can use textEdit.append() or textEdit.setText() to add the data in the array to the text box in the scroll area. The documentation says it all, really, albeit in C rather than python, but its obvious what you need to do:
QLabel *imageLabel = new QLabel;
QImage image("happyguy.png");
imageLabel->setPixmap(QPixmap.fromImage(image));
scrollArea = new QScrollArea;
scrollArea->setBackgroundRole(QPalette.Dark);
scrollArea->setWidget(imageLabel);

Categories