使用Tkinter在闪烁的光标下打开一个新窗口

时间:2015-12-12 07:11:24

标签: python user-interface tkinter

通常我们得到坐标并在那里打开一个新窗口。我需要的是在Tkinter文本框的闪烁光标下方打开一个窗口。关于如何根据屏幕中的高度和宽度像素获取坐标,我很遗憾。

1 个答案:

答案 0 :(得分:2)

您需要获取文本窗口小部件相对于屏幕的当前位置以及窗口小部件的插入光标的边界框,该窗口相对于窗口小部件。

如果文本小部件的元素当前不可见,则其边界框为None;在这种情况下,您需要使用.see方法滚动文本以使元素可见。

这个程序是为Python 2编写的,所以如果你在Python 3上运行它,你需要将import语句改为import tkinter as tk

#!/usr/bin/env python

''' Text Location Demo
    Open a Tkinter window just under the location of the insertion cursor 
    of a Text widget.

    See http://stackoverflow.com/q/34237313/4014959

    Written by PM 2Ring 2015.12.12
'''

import Tkinter as tk

#Some random text to display in the Text widget
lorem_ipsum = '''Lorem ipsum dolor sit amet, consectetur adipiscing
elit. Aenean lacinia tortor quis quam vehicula semper. Curabitur
faucibus, purus a egestas bibendum, velit metus hendrerit nulla, non
lobortis dolor mi in dolor. Aliquam ultrices felis sit amet dolor
gravida, id ullamcorper odio rutrum. Fusce consectetur tempor nibh, non
dictum dolor dictum nec. In hac habitasse platea dictumst. Morbi laoreet
consequat metus, at lacinia nisl suscipit id. Quisque vitae sodales
velit, a lobortis nisl. Praesent varius convallis efficitur. Vivamus
fringilla at risus nec viverra. Proin suscipit, lorem sed laoreet
ultricies, velit massa ornare nunc, vel egestas nibh ex vitae leo.'''

lorem_ipsum = lorem_ipsum.replace('\n', ' ')

class TextLocationDemo(object):
    ''' Text widget cursor location demo '''
    def __init__(self):
        root = tk.Tk()
        root.title("Text Location Demo")

        tk.Button(root, text="Show cursor location", 
            command=self.location_cb).pack()

        # Create a Text widget, with word wrapping
        self.textwidget = tw = tk.Text(root, wrap=tk.WORD)
        tw.pack()
        tw.insert(tk.END, lorem_ipsum)

        root.mainloop()

    def alert(self, geometry, msg):
        ''' Display `msg` in an Alert with given geometry,
            which is a tuple of (width, height, ox, oy)
        '''
        top = tk.Toplevel()
        # widget geometry parameter must be given in X windows format
        top.geometry("%dx%d%+d%+d" % geometry)

        msg = tk.Message(top, text=msg, width=geometry[0])
        msg.pack()

        button = tk.Button(top, text="Ok", command=top.destroy)
        button.pack()

    def location_cb(self):
        ''' Determine the location of the insertion cursor
            and display it in a window just under that location
        '''
        w = self.textwidget

        # Get the Text widget's current location
        pos_x, pos_y = w.winfo_rootx(), w.winfo_rooty()

        # Get the bounding box of the insertion cursor
        cursor = tk.INSERT
        bbox = w.bbox(cursor)
        if bbox is None:
            print('Cursor is not currently visible. Scrolling...')
            w.see(cursor)
            bbox = w.bbox(cursor)

        bb_x, bb_y, bb_w, bb_h = bbox

        #Open a window just beneath the insertion cursor
        width = 200
        height = 80
        ox = pos_x + bb_x
        oy = pos_y + bb_y + bb_h
        s = 'Cursor: (%d, %d)' % (ox, oy)
        print(s)

        geometry = (width, height, ox, oy)
        self.alert(geometry, s)


TextLocationDemo()