1
votes

Consider you have several items in tk frame and use grid to place them. If dropdown OptionMenu "om" is one of the elemens then I find impossible to place it on top of another element.

As a minimal representative example consider a frame with one a label "lab_1" and the dropdown optionmenu "om_1". Once created properly, use grid to place them row/column-wise.

import tkinter as tk
...
self.lab_1.grid(row = 1, column = 0, columnspan = 2, padx = 10, sticky = tk.W)
self.om_1.grid(row  = 2, column = 0, columnspan = 1, padx = 10, sticky = tk.W)

Even if you swap the rows (om_1 row:2, lab_1 row:1), and set sticky = tk.NW for "om_1",

self.om_1.grid(row  = 1, column = 0, columnspan = 1, padx = 10, sticky = tk.NW)
self.lab_1.grid(row = 2, column = 0, columnspan = 2, padx = 10, sticky = tk.W)

"om_1" will appear always at the bottom. I can round the issue using .place instead of .grid only for the optionmenus, but am I doing something not elegant/pythonic?

I add here a Minimal Complete Verifiable example.

# -*- coding: utf-8 -*-
"""
Spyder 3.3.3, Python 3.6.8 64bits, Qt 5.12.1, PyQt5 5.12, Win 7 64 bits
Minimal Complete Verifiable example
Created on Tue Aug 20 20:40:37 2019

"""

# -*- coding: utf-8 -*-

import tkinter as tk
from tkinter import Tk, Label, Frame, Entry, Button


# =============================================================================
#  GUI TOP
# =============================================================================

def gui_top():

    # creates window
    root = tk.Tk()

    # modifies window
    root.title("GUI")
    root.geometry("800x500") # height x width

    # app object
    app = cls_app(root)

    # launches gui
    root.mainloop()

# =============================================================================
# cls app
# =============================================================================

class cls_app(tk.Frame):
    """GUI with openfile dialog"""


    def __init__(self, master):
        """Init frame"""

        # init
        self.frm = tk.Frame.__init__(self,master)
        self.grid()
        self.master = master
        self.met_initwidgets()

    #enddef __init__



    def met_initwidgets(self):

        # label lab_1
        self.lab_1      = tk.Label(self, text = 'This is label 1')

        # dropdown optionmenu om_1
        self.tkstr_om_1 = tk.StringVar(self)
        set_om_1        = {'default opt, opt_2, opt_3'}
        self.tkstr_om_1.set('default opt') # default option
        self.om_1       = tk.OptionMenu(self.master, self.tkstr_om_1, *set_om_1)

        # grid (force om_1 to be upper)
        self.om_1.grid(row   = 1, column = 0, columnspan = 1, padx = 10, sticky = tk.NW)
        self.lab_1.grid(row  = 0, column = 0, columnspan = 1, padx = 10, sticky = tk.W)

    #enddef met_initwidgets

#endcls app

# =============================================================================
# MAIN
# =============================================================================

if __name__ == '__main__':
    """ test pad """
    gui_top()
#endif main

Suggestions are appreciated.. kind regards

1
If your place packing manager is used only in relative meaning and you don't mix packers on the same level, then using the pack manager - if it solves your problem - is a justified elegant solution. - ipaleka
Works just fine for mw with Python 3.6.5 on Windows10. But then again I had to add some code to make it run. Perhaps if you posted a Minimal, Complete, and Verifiable example we could be of more help. - figbeam
Thank you for both answers. I rounded the issue, but I will enrich the question with a minimal complete verifiable example in order to clarify the matter with the aim to help potential future users. Scenario: I run such MCV example on Spyder v3.3.3 editor, with Python 3.6.8 64bits, Qt 5.12.1, PyQt5 5.12, Windows 7. Regards - José Crespo Barrios

1 Answers

2
votes

You are putting the label in self but putting the option menu in self.master.