I just started learning pyqt5 qt designer. I used to use tkinter. I have a problem, and I can't figure out how to do it. As the picture shows, there are QCheckBox and QLineEdit. Keep the LineEdit field 'disabled' when checkbox is not checked; When the CheckBox is checked, I try to get the LineEdit field to be activated in the 'normal' position.
when i use tkinter,
txtSample.configure(state=DISABLED)
txtSample = Checkbutton( text='TEST', variable=var, onvalue=1, offvalue=0,font('arial',16,'bold'))
txtSample = Entry(font=('arial',16,'bold'), bd=8, width=6, justify='left',state=DISABLED)
def checkbuttonSample():
if(var.get() == 1):
txtSample.configure(state=NORMAL)
elif var.get()== 0:
txtSample.configure(state=DISABLED)`
I would use similar code like this.But I couldn't find a solution and I am looking for a solution about this issue. Thank you for your answers in advance.
From code it's pretty simple: you need to connect the toggled signal of the checkbox to the setEnabled() slot of the line edit:
self.lineEdit.setEnabled(False)
self.checkBox.toggled.connect(self.lineEdit.setEnabled)
You can also do it directly in Designer:
select the line edit;
on the Property Editor panel, uncheck the "Enabled" option;
enter the "Edit Signals/Slots" mode (from the tool bar or the "Edit" menu);
press the left mouse button on the checkbox, move the mouse on the line edit, then release the button;
in the "Configure Connection" dialog that will be opened afterwards, select the "toggled(bool)" signal on the left, check the "Show signals and slots inherited from QWidget" option, and select "setEnabled(bool)" slot, then click "Ok";
Related
I am making an application where I want to create a dropdown menu if anyone clicks on the Qaction.
My code
self.navtb = QToolBar("Navigation")
self.navtb.setIconSize(QSize(25, 25))
self.navtb.setMovable(False)
self.addToolBar(self.navtb)
option_btn = QAction(QIcon(os.path.join('images', 'options.png')), "Option", self)
self.navtb.addAction(option_btn)
A QAction can have an associated menu which you can simply set with setMenu(). This menu will pop up (drop down) on click+hold.
Now all you need is to set your button to directly go for the menu on click by altering its popup mode. Note that while the wording pop up is used, the menu will be a proper drop-down menu in a toolbar scenario.
In your example it would roughly translate to:
option_btn.setMenu(...)
self.navtb.widgetForAction(option_btn).setPopupMode(QToolButton.InstantPopup)
For reference, this is how I do it in my code in C++:
// initialize compute menu and let button display menu without holding mouse
actionComputeDisplay->setMenu(new QMenu(widget));
auto btn = qobject_cast<QToolButton*>(toolBar->widgetForAction(actionComputeDisplay));
btn->setPopupMode(QToolButton::ToolButtonPopupMode::InstantPopup);
How to add an 'about' button to the menu bar of your main window - which when clicked directly opens a dialog with some about text - using PyQT?
Or is that impossible?
Having had a look at the documentation/question and answers online having to do with the menu bar, I get the impression that the QMenuBar only supports triggering events via 'QAction's via menu drop-downs. However I dont want a drop-down for the about button but rather would like it to trigger some showAboutDialog method.
If you have any ideas/links please let me know.
You can add a QAction object directly to the menubar of your MainWindow. Use the QMenuBar.addAction() method for this:
class YourMainWindow(QMainWindow):
def __init__(self):
super().__init__()
menu = QMenuBar()
menu.addAction(show_about_dialog_action)
self.setMenuBar(menu)
I want to have a menu that shows a modal dialog box. Everything is fine, until I add an accelerator. If I do this and use the accelerator to access to dialog, it hangs. I suspect that wait_window, used inside the modal dialog box is somehow in conflict with the mainloop, when called from a "bind". Here is an example:
import tkinter
from tkinter import simpledialog
class App(tkinter.Tk):
def __init__(self):
tkinter.Tk.__init__(self)
self.bind_all("<Control-f>", lambda event: self.menu_file())
menubar = tkinter.Menu(self)
fileMenu = tkinter.Menu(menubar, tearoff=False)
fileMenu.add_command(label="File", underline=0,
command=self.menu_file, accelerator="Control+f")
# fileMenu.add_command(label="File", underline=0,
# command=self.menu_file)
menubar.add_cascade(label="File",underline=0, menu=fileMenu)
self.config(menu=menubar)
def menu_file(self):
simpledialog.Dialog(self,"Message")
app=App()
app.mainloop()
If in the above code I comment out the line that adds the accelerator and uncomment the subsequent line, there is no hangup (I can of course still use Ctrl+F to access the dialog box). The only problem is that the accelerator string is not shown next to the File menu. According to the tkinter documentations on the web that I have found, adding the accelerator should only change how the menu is shown and nothing else, so I am really puzzled. Anyone any ideas? (I could of course emulate accelerators by modifying the strings to be displayed, but I would not consider this as an elegant solution.)
As I have noticed, this is a Mac-specific bug.
Following the workaround suggested for a known Tk bug on Mac (see link), changing the line which binds the menu method to the keystroke to the following:
self.bind_all("<Command-f>", lambda event: self.after(100,self.menu_file))
is "fixing" the bug. They also suggest to increase 100 to 150 on slower systems. Hmm..
I'm trying to make a Tkinter menu that is like a taskbar checker.
So if I go to this menu and check a box, a specific button then appears on my window, and then the user can select multiple buttons based on what they want.
The program is just a bunch of buttons that after entering text in my text field, and clicking the button, a web browser launches with a search of the website that the button is linked to.
How can I make a menu like I mentioned above?
Edit:
I've just tried basic menu stuff:
buttonmenu = Menu(menubar, tearoff=0)
buttonmenu.add_command(label="button1", command=turnbuttononoff)
buttonmenu.add_command(label="button2", command=turnbuttononoff)
buttonmenu.add_command(label="button3", command=turnbuttononoff)
buttonmenu.add_command(label="button4", command=turnbuttononoff)
buttonmenu.add_command(label="button5", command=turnbuttononoff)
This just creates a basic menu. And if I could have a function that triggers a button to be turned on or off that would be great.
So essentially just a function to swap a button from being shown to not being shown
def turnbuttononoff():
#togglebutton here
ANSWER:
I made a dictionary of the data of where each button was stored, and then checked to see if the button was active, and if it was, turned it off, and if it was inactive, turn it off.
Making this a command lambda function for each button works.
def Toggle_Button(myButton):
if myButton.winfo_ismapped()==1:
myButton.grid_forget()
else:
myButton.grid(row=gridData[myButton][0],column=gridData[myButton][1])
gridData = {}
gridData[button] = [row,col]
def Toggle_Button(myButton):
if myButton.winfo_ismapped()==1:
myButton.grid_forget()
else:
myButton.grid(row=gridData[myButton][0],column=gridData[myButton][1])
If you already have buttons on a grid, use button.grid_info to find what you need, it returns a dictionary.
Using wxPython, I created a taskbar icon and menu.
Everything works fine (in Windows at least) upon right-click of the icon: i.e., the menu is displayed, and automatically hidden when you click somewhere else, like on Windows' taskbar.
Now I do want to have the menu appear when the icon is left-clicked as well.
So I inserted a Bind() to a left-click in the Frame class wrapper, calling the CreatePopupMenu() of the taskbar icon:
import wx
class BibTaskBarIcon(wx.TaskBarIcon):
def __init__(self, frame):
wx.TaskBarIcon.__init__(self)
self.frame = frame
icon = wx.Icon('test_icon.ico', wx.BITMAP_TYPE_ICO)
self.SetIcon(icon, "title")
def CreatePopupMenu(self):
self.menu = wx.Menu()
self.menu.Append(wx.NewId(), "dummy menu ")
self.menu.Append(wx.NewId(), "dummy menu 2")
return self.menu
class TaskBarFrame(wx.Frame):
def __init__(self, parent, title):
wx.Frame.__init__(self, parent, style=wx.FRAME_NO_TASKBAR)
...
self.tbicon = BibTaskBarIcon(self)
wx.EVT_TASKBAR_LEFT_UP(self.tbicon, self.OnTaskBarLeftClick)
...
def OnTaskBarLeftClick(self, evt):
self.PopupMenu(self.tbicon.CreatePopupMenu())
...
def main(argv=None):
app = wx.App(False)
TaskBarFrame(None, "testing frame")
app.MainLoop()
This works fine, except that the menu does not disappear automatically when you click somewhere else on your screen. In fact, left-clicking multiple times on the icon creates multiple menus. The only way to hide the menu(s) is to click on one of its items (which you don't always want). I've looked at the available methods of TaskbarIcon, but I failed to be clear about which one to use to hide the menu (.Destroy() didn't work). Moreover, I don't know which event to bind it to (there is a EVT_SET_FOCUS, but I couldn't find any EVT_LOOSE_FOCUS or similar).
So, how to hide the menu upon losing focus?
EDIT: I've inserted a bit more code, to make it more clear
Ah, I've discovered what went wrong. In the statement
self.PopupMenu(self.tbicon.CreatePopupMenu())
I had bound the popup menu to the frame, instead of to the taskbar icon.
By changing it to:
self.tbicon.PopupMenu(self.tbicon.CreatePopupMenu())
all is working well now.
Thanks for all remarks
I think the problem here is that the PopupMenu is usually used in a program's context, not a little icon in the system tray. What that means is that in a normal frame, the popup menu would detect the click the you clicked off of it. Here, you are clicking outside of the wxPython program. Also, the PopupMenu is usually used with EVT_CONTEXT_MENU, not this taskbar event.
You can try wx.EVT_KILL_FOCUS and see if that works since it should theoretically fire when you click off the menu. Or you could ask on the official wxPython forum here: http://groups.google.com/group/wxpython-users/topics
Mike Driscoll
Blog: http://blog.pythonlibrary.org