0

I would like to change the color of the menu bar and that of the title.

Here is the example of what I would like to have.

example

Is it possible?

1 Answers1

7

To give an Exampel of what you trying to do:

import tkinter as tk
from tkinter import ttk

class App(tk.Tk):
    def __init__(self):
        super().__init__()
        self.geometry("400x200")
        self.configure(background='black')
        self.overrideredirect(1)
        self.attributes("-topmost", True)
        
    def startMove(self,event):
        self.x = event.x
        self.y = event.y

    def stopMove(self,event):
        self.x = None
        self.y = None

    def moving(self,event):
        x = (event.x_root - self.x)
        y = (event.y_root - self.y)
        self.geometry("+%s+%s" % (x, y))

    def exit(self):
        self.destroy()


def save():
    print ('save')
    return None
def add():
    print('add')
    return None

  

class MenuBar(tk.Frame):
    def __init__(self, master=None):
        tk.Frame.__init__(self, master, bd=1, relief='raised')
        self.master=master
        self.configure(background='black',
                       cursor='hand2')

        file = tk.Menubutton(self, text='File',
                             background='black',
                             foreground='white',
                             activeforeground='black',
                             activebackground='white'
                             )
        file_menu = tk.Menu(file,tearoff=0)
        file_menu.add_command(label='save', command=save,
                              background='black',
                              foreground='white',
                              activeforeground='black',
                              activebackground='white'
                              )
        
        file.config(menu=file_menu)
        file.pack(side='left')

        edit = tk.Menubutton(self, text='Edit',
                             background='black',
                             foreground='white',
                             activeforeground='black',
                             activebackground='white'
                             )
        edit_menu = tk.Menu(edit,tearoff=0)
        edit_menu.add_command(label='add', command=add,
                              background='black',
                              foreground='white',
                              activeforeground='black',
                              activebackground='white'
                              )

        edit.config(menu=edit_menu)
        edit.pack(side='left')

        close = tk.Button(self, text='X', command=lambda:root.exit(),
                          background='black',
                          foreground='white')
        close.pack(side='right')

def show():
    print('show')
    return None
def ex_it():
    print('exit')
    return None

class MainFrame(tk.LabelFrame):
    def __init__(self, master=None):
        tk.LabelFrame.__init__(self, master, bd=1, relief='raised', text='MainFrame', background='black', foreground='white')
        self.master=master
        self.note = tk.Label(self, text='Your typed chars appear here:',
                             background='black',
                             foreground='white',
                             )
        self.note.grid(column=0, row=0, columnspan=2, sticky='w')
        self.entry = ttk.Entry(self, style='My.TEntry')
        self.entry.grid(column=0,row=1,columnspan=3, sticky='ew')
        self.columnconfigure(0, weight=1)
        self.b_frame=tk.Frame(self, bg='black')
        self.b_frame.grid(column=0,row=2,sticky='w')
        self.sh_b = tk.Button(self.b_frame, text='Show', command=show)
        self.ex_b = tk.Button(self.b_frame, text='Exit', command=ex_it)
        self.sh_b.grid(column=0, row=0, sticky='w')
        self.ex_b.grid(column=1, row=0, sticky='w', padx=5)

root = App()

menubar = MenuBar(root)
menubar.pack(side='top', fill='x')

mainframe = MainFrame(root)
mainframe.pack(fill='both', expand=1)

menubar.bind("<Button-1>", root.startMove)
menubar.bind("<ButtonRelease-1>", root.stopMove)
menubar.bind("<B1-Motion>", root.moving)

style = ttk.Style(root)
style.element_create("plain.field", "from", "clam")
style.layout("My.TEntry",
             [('Entry.plain.field', {'children': [(
                 'Entry.background', {'children': [(
                     'Entry.padding', {'children': [(
                         'Entry.textarea', {'sticky': 'nswe'})],
                                       'sticky': 'nswe'})], 'sticky': 'nswe'})],
                                     'border':'2', 'sticky': 'nswe'})])
style.configure("My.TEntry",
                 foreground="white",
                 fieldbackground="grey")

root.mainloop()

Have fun with it!

Explaination

First, I've created 3 objects using classes and they look like this:

The Application / our window that inharets from Tk()

class App(tk.Tk):
    def __init__(self):
        super().__init__()

Then the Menubar which inharets from Frame and looks like:

class MenuBar(tk.Frame):
    def __init__(self, master=None):
        tk.Frame.__init__(self, master, bd=1, relief='raised')

and the MainFrame which inharets from the LabeFrame class of tkinter:

class MainFrame(tk.LabelFrame):
    def __init__(self, master=None):
        tk.LabelFrame.__init__(self, master, bd=1, relief='raised', text='MainFrame', background='black', foreground='white')

To learn more about classes and the init method [click] To understand the syntax self. [click]

Let's take a closer look to the App:


self.geometry("400x200")
self.configure(background='black')
self.overrideredirect(1)
self.attributes("-topmost", True)
  • with the geometry method we are define the width=400 and height=200 in pixels.
  • Then we configure the background with the line:

self.configure(background='black')

Sets or gets the override redirect flag. If non-zero, this prevents the window manager from decorating the window. In other words, the window will not have a title or a border, and it cannot be moved or closed via ordinary means.

  • and we finally use the attributes method for Toplevels and set the argument topmost to true that does:

(Windows) If set, this window is always placed on top of other windows. Note that in this release, this attribute must be given as “-topmost”.


The biggest problem after using overrideredirect is that you can't move your window anymore, cause there is no border/Title- or Menubar of the window manager anymore. So we need to carry it by ourself with using this code:

def startMove(self,event):
    self.x = event.x
    self.y = event.y

def stopMove(self,event):
    self.x = None
    self.y = None

def moving(self,event):
    x = (event.x_root - self.x)
    y = (event.y_root - self.y)
    self.geometry("+%s+%s" % (x, y))

And what this code does is to get the current mouse postion by clicking/Button-1 with the event manger

event.x or event.y means:

The current mouse position, in pixels.

event.x_root or event.y_root means:

The current mouse position relative to the upper left corner of the screen, in pixels.

and by substracting the one from the other we get the offset, that we need for our geometry method to "move".


Thingamabobs
  • 4,666
  • 3
  • 8
  • 33
  • Your code works. But I still can't adapt it. I have a question. Can you give me the code to display the title, put the menu bar in black, but the rest in white? I'm sorry I'm a beginner –  Jul 31 '20 at 12:31
  • I will write an explaination soon. But first you should know there is no "normal" menubar anymore, I had removed the menubar of the system and wrote my own in the class Menubar. delete this line self.configure(background='black') in the App class and see if it solves your problem. – Thingamabobs Jul 31 '20 at 12:36
  • @LucySmith updated to a valid point. I hope this helps – Thingamabobs Jul 31 '20 at 14:32
  • Thank you, you help me a lot. But I still can't do it. I posted some of my code here. https://pastebin.com/Wn2rMK6t –  Aug 01 '20 at 07:58
  • @LucySmith this hasn't much to do with the code I wrote and I really dont want to go all this through. But you can try to use self.configure(bg='color_of_your_choice') in the app class and see if it works. – Thingamabobs Aug 01 '20 at 08:08