I really hope that you understand the following question, because I wasn't sure how to ask this question so I hope you can help me, if not let me now
I want to make a program to practise my python programming skill. I want to make a store program where an employee could input items with the price, and where he could sell the items. I want to make it that one “page” is the items input an another “page” is the sell page. To so that I want to make a menu bar where the employee could press on the let's say input button and go to input items page, but when he wants to sell items he presses on the sell button and then he goes to the sell page but only the screen changes, not that there comes another tab/window.
I really hope I explained my problem good enough
Thanks in advance!!
Based on your comments to the question, it appears your main problem is that you don't know how to make a menubar, so I will address that part of the question.
Every top level window (instances of Tk and Toplevel) have a menu attribute that can be set to an instance of a Menu object. This menu can itself have dropdown menus, and that combination is what makes a menubar.
In order to make this work you must first create the menu, and then associate that menu with the window.
import tkinter as tk
root = tk.Tk()
self.menubar = tk.Menu()
root.configure(menu=self.menubar)
To create the sub-menus you must do something very similar. First, create a new Menu instance, then associate it with the menubar using add_cascade. Typically, the menu will be a child of the menubar. You use the add_command method to add items to the sub-menu.
In your case, you might want to create a "View" menu with items for switching between "Input" and "Sell". It would look something like this:
viewMenu = tk.Menu(self.menubar)
self.menubar.add_cascade(label="View", menu=viewMenu)
viewMenu.add_command(label="Input", command=self.switch_to_input)
viewMenu.add_command(label="Sell", command=self.switch_to_sell)
Example
Here is a complete working example. To keep it simple and on topic it doesn't actually switch pages. Instead, it just displays the "page" in a label.
import tkinter as tk
class MenuExample:
def __init__(self):
self.root = tk.Tk()
self.label = tk.Label(self.root, width=25)
self.label.pack(side="top", fill="both", expand=True, padx=20, pady=20)
self._create_menubar()
def _create_menubar(self):
# create the menubar
self.menubar = tk.Menu(self.root)
self.root.configure(menu=self.menubar)
# File menu
fileMenu = tk.Menu(self.menubar)
self.menubar.add_cascade(label="File", menu=fileMenu)
fileMenu.add_command(label="Exit", command=self.root.destroy)
# View menu
viewMenu = tk.Menu(self.menubar)
self.menubar.add_cascade(label="View", menu=viewMenu)
viewMenu.add_command(label="Input", command=self.switch_to_input)
viewMenu.add_command(label="Sell", command=self.switch_to_sell)
def switch_to_input(self):
# put the code to switch to the input page here...
self.label.configure(text="you clicked on View->Input")
def switch_to_sell(self):
# put the code to switch to the sell page here...
self.label.configure(text="you clicked on View->Sell")
app = MenuExample()
tk.mainloop()
Related
I am developing a Desktop application by Python tkinter library. I didn't write code for menu bar in the application by default it's creating on Mac. I want to listen the action, I can listen the Quit button
app.createcommand("::tk::mac::Quit", on_closing)
I don't know how to listen the About button action. I have tried with
::tk::mac::About and ::tk::mac::standardAboutPanel. Can you suggest what to use to listen the About button on mac.
Note: It's default menu created by mac. So, just we need to listen the action that's it. If we listen we can call the method for the about.
You can't explicitly listen for activation of the default "About" menu. You can, however, create your own "About" menu.
There are two important steps. First, the internal name of the menu needs to be "about", and this menu needs to be added to the menubar before you add the menubar to the root window.
If you follow those two rules, any menu items you create will be placed before the default menu items. Here's a simple example:
import tkinter as tk
root = tk.Tk()
def show_about():
top = tk.Toplevel()
label = tk.Label(top, text="This is my custom 'about' window")
button = tk.Button(top, text="Ok", command=top.destroy)
button.pack(side="bottom", pady=20)
label.pack(padx=20, pady=20)
menubar = tk.Menu(root)
apple_menu = tk.Menu(menubar, name="apple")
menubar.add_cascade(menu=apple_menu)
apple_menu.add_command(label="About mediavalet", command=show_about)
root.configure(menu=menubar)
root.mainloop()
A good reference for platform-specific menus is the Menu tutorial on tkdocs.com
below is just a pseudo code what i am trying to do.
so there is a button which i press to add more buttons but i store button widget in a list, which i can access by its index number.
# initialize class: this is just a pseudo code of what i am trying to do
def __init__(self,parent=None):
self.ButtonWidgetList=list()
self.i=0
self.MakeButton=QtWidgets.QPushButton(self) #assume this button is displayed and works
self.MakeButton.clicked.connect(self.NextButton) # assume this button calls Function NextButton
def NextButton(self):
self.ButtonWidgetList[self.i]=QtWidgets.QPushButton()
self.i=self.i+1
How can i access individual buttons stored in list by .setStyleSheet as i need it to change its image on press for example:
self.ButtonWidgetList[self.i].setStyleSheet("QPushButton#ButtonWidgetList{\n"
"border-image:url(:/imageA)};\n"
"QPushButton#ButtonWidgetList:pressed{\n"
"border-image:url(:/imageB)};\n"
i hope my question is understandable.
I have dynamic button label, which changes everytime you click it. The problem is, when text on the button changes, the same goes with button width. For this reason I set fixed width for my button.
After that, another problem appeared. Content is centered within button, so on every change image and label move a bit. For this reason I tried to position everything to the left side to reduce content trembling.
I looked through docs and found that button widget supports anchor option to position content. However, when I try it, I'm getting error:
_tkinter.TclError: unknown option "-anchor"
I found another option, justify, but result is the same:
_tkinter.TclError: unknown option "-justify"
Anyone knows how to deal with it? I'll share my code with you:
self.btnServiceIo = ttk.Button(
top_buttons_frame,
text="Usługa automatyczna",
image=self.ioBtnImg_off,
compound=tk.LEFT,
width=30,
justify=tk.LEFT,
anchor='w')
self.btnServiceIo.pack(side=tk.LEFT)
self.btnServiceIo.bind("<ButtonRelease>", self.IObuttonToggle)
(I don't use justify and anchor at the same time, I just posted them together to show you the way I'm using it)
I'll post the picture of my app for your attention. My client would like to have not only toggle image which states the status of some service, but also text information nearby.
For ttk buttons you can set the anchor option in the ttk style, see the anchor entry on this page.
So for example:
import tkinter as tk
from tkinter import ttk
from PIL import Image, ImageTk
root = tk.Tk()
s = ttk.Style()
s.configure('TButton', anchor=tk.W)
buttonImage = Image.open('test.png')
buttonPhoto = ImageTk.PhotoImage(buttonImage)
btnServiceIo = ttk.Button(
root,
text="Usługa automatyczna",
image=buttonPhoto,
compound=tk.LEFT,
width=30)
btnServiceIo.pack(side=tk.LEFT)
root.mainloop()
Answer from #fhdrsdg was almost perfect, but it messed with some of my simple buttons with text only, centered in the button. I had to make dedicated style for my button as following:
# Access ttk style object
s = ttk.Style()
# Set dedicated style for button, derived from main button class
s.configure('service-io.TButton', anchor=tk.W)
self.ioBtnImg_off = tk.PhotoImage(file='../img/io.png')
self.ioBtnImg_on = tk.PhotoImage(file='../img/io_on.png')
self.btnServiceIo = ttk.Button(
top_buttons_frame,
text="Usługa automatyczna",
image=self.ioBtnImg_off,
compound=tk.LEFT,
width=30,
style='service-io.TButton' # use dedicated style
)
I am pretty new at both Python and wxPython. Anyway, after having followed the official tutorial where they explain how to do a basic text editor, I decided to go ahead and write a real text editor.
Now, my text editor consists of a MainWindow (which inherits from wx.Frame), which in turn contains a Notebook (inheriting from wx.Notebook) which in turn contains several tabs (a custom class inheriting from wx.Panel).
If I didn't misunderstand, events in wxPython can be detected and bounded to specific objects via the Bind() function.
Here's my custom panel class:
class TabContent(wx.Panel) :
def __init__(self, parent) :
# Calls the constructor for wx.Panel
wx.Panel.__init__(self, parent = parent, id = wx.ID_ANY)
# Creates a vertical sizer
sizer = wx.BoxSizer(wx.VERTICAL)
# Creates an empty multiline wx.TextCtrl
textArea = wx.TextCtrl(self, style = wx.TE_MULTILINE)
# Adds the text area to the sizer
sizer.Add(textArea, 1, wx.EXPAND | wx.ALL, 2)
# Sets the previously created sizer as this panel's sizer
self.SetSizer(sizer)
# Sets up events
self.Bind(wx.EVT_RIGHT_DOWN, self.onMouseLeftClicked)
def onMouseLeftClicked(self, event) :
print("Left button of the mouse was clicked\n")
I'd like to be able to detect right clicks on the tab itself (for example I could open a menu or just print something for the sake of testing wxPython functions). However, clicking with the mouse does not print anything. Any idea why?
By the way, I am on ArchLinux, using PyCharm Community Edition 2016.2.3, Python 3.5.2 and wxpython 3.0.2.
The event was actually being caught, but only on the very thin border of the tab.
Solved by putting the event handler in the Notebook class.
I want to add a scrollbar to my main window
Here's a simplified version of my code since mine is too long.
class Main(QtGui.QWidget):
def __init__(self):
super(Main, self).__init__()
verticalLayout = QtGui.QVBoxLayout()
self.setGeometry(0,0,400,400)
self.setLayout(verticalLayout)
label_1 = QtGui.QLabel("label 1")
self.verticalLayout.addWidget(label_1)
...(many more that exceed my computer screen)
so I've been reading a lot of posts about scrollbars but I'm still not quite sure as to how to implement it.
Within your main window, you need to create a Scroll Area.
http://pyqt.sourceforge.net/Docs/PyQt4/qscrollarea.html