7
votes

Placer une fenêtre enfant par rapport au parent dans Tkinter Python

J'ai un widget parent qui contient un bouton. Lorsque vous appuyez sur le bouton, je voudrais ouvrir une fenêtre sans bordure (I.e. No Windows de décoration) sous le widget parent aligné sur le côté gauche de celui-ci. Je suis perplexe que le seul moyen (il semble) de régler la position d'une fenêtre utilise .geométrie () code> mais pire, je n'arrive pas à obtenir les coordonnées absolues du widget parent - dont j'ai besoin pour .geométrie () code>, seuls les compensations du parent du parent. Jusqu'à présent, mon code est le suivant:

# This is the child which appears when the button is pressed.
class ChildPopUpWindow(Frame):
    def __init__(self, parentWgdt):
        win = Toplevel(parentWgdt)
        geom = str(parentWgdt.winfo_x()) + '+' + str(parentWgdt.winfo_y() + parentWgdt.winfo_height())
        win.overrideredirect(1) # No win decoration.
        win.bd = 10
        win.relief = GROOVE
        win.geometry( geom )
        Frame.__init__(self, win)
        # etc. etc.

     # ... and this is the handler for the button being pressed.
     def onDropDown(self):
        popUp = ChildPopUpWindow(self)


3 commentaires

Vous dites que vous souhaitez créer une fenêtre contextuelle et votre nom de classe indique Popupwindow, mais vous hériter du cadre plutôt que de TALLLEVEL. Y at-il une raison à cela? Je ne comprends pas bien comment vous utilisez cela. Est le bouton pour afficher la fenêtre contextuelle à l'intérieur du cadre de l'enfantPopupwindow?


Désolé, cela n'était pas très clair: Ondropdown est un gestionnaire du cadre dans lequel réside le bouton. En cliquant sur le bouton, l'idée est de contourner une fenêtre sans cadre (c'est-à-dire sans fenêtres maximisant / minimiser / minimiser / fermer les boutons, etc.) directement sous la trame avec le bouton. Cela agirait essentiellement de manière modale, sauf que soit une sélection sur la fenêtre contextuelle, ou appuyer à nouveau sur le bouton, le fermerait. De cette façon, cela fonctionnerait un peu comme dites un calendrier ou une liste déroulante de la couleur de la couleur.


@BryanoAkley: La confusion de toplevel / cadre est due à moi faire de nombreuses tentatives différentes pour que cela fonctionne, j'ai peur. La plupart des exemples que j'ai trouvés semblent créer la fenêtre Toplevel puis transmettez-le comme un paramètre à une classe de trame-inhibeting. Je voulais suivre cela et essayé de définir les paramètres de la fenêtre Toplevel avant le cadre en les utilisant dans son constructeur, même si je voulais garder ces personnes encapsulées dans la catégorie CODEPOPOPUWINDOW . S'il vous plaît, vous vous sentiez ffr libre de commenter / corriger.


3 Réponses :


7
votes

La réponse courte est, utilisez winfo_rootx code> et winfo_rooty code> pour obtenir les coordonnées par rapport à l'écran. Et oui, wm_geométrie code> est le moyen de placer une fenêtre de toplevel précisément.

Par exemple: p>

    x = parentWgdt.winfo_rootx()
    y = parentWgdt.winfo_rooty()
    height = parentWgdt.winfo_height()
    geom = "+%d+%d" % (x,y+height)


1 commentaires

Merçi pour la confirmation. Cela semble être essentiellement ce que j'ai donc je suppose qu'il doit y avoir une autre raison pour laquelle cela ne fonctionne pas. D'accord sur les abréviations: j'ai obscurci le code (qui est la propriété intellectuelle client) à la hâte avant de poster.



0
votes

Selon TK Manuel " https: // www. tcl.tk/man/tcl8.4/tkcmd/winfo.htm#m52 " Si vous avez besoin de la vraie largeur immédiatement après la création d'un widget, appelez la mise à jour forte> pour forcer le gestionnaire de géométrie à l'organiser ou utiliser WinFo Reqwidth pour obtenir la largeur demandée par la fenêtre au lieu de sa largeur réelle.

# This code works perfectly
self.update()

self.geometry("+%d+%d" % (self.parent.winfo_rootx()+50,
                          self.parent.winfo_rooty()+50
                         )
             ) 


0 commentaires

0
votes

Pour centrer une fenêtre modale à propos d'une fenêtre sa mère, je le fais:

    alto_modal = 100
    ancho_modal = 250
    alto_parent = parent.winfo_height()
    ancho_parent = parent.winfo_width()
    x = (ancho_parent - ancho_modal) // 2
    y = (alto_parent - alto_modal) // 2
    self.geometry('{}x{}+{}+{}'.format(ancho_modal, alto_modal, x, y))


0 commentaires