python - wx.TextCtrl 中插入点位置的弹出菜单

标签 python contextmenu wxwidgets popupmenu wx.textctrl

有人知道如何使用 wxPython 在 TextCtrl 对象中创建自定义上下文菜单吗?

目前,我可以创建一个自定义菜单,但这个菜单出现在鼠标光标位置 enter image description here ,当原来的出现在文本光标位置 enter image description here 时当按下[菜单]键时enter image description here .

最佳答案

好的,

可以以某种方式实现这一点但是这只有效

  1. 当字体为等宽字体时(请参阅下面的代码),
  2. 当焦点行中没有制表符(“\t”)时...

简单来说:获取文本光标的位置enter image description here转换为行/列坐标并将其乘以字符大小。这给出了所需的弹出菜单位置。

import wx

# Test context menu that should be displayed at the insertion point position 
# in the TextCtrl object
class CustomMenu(wx.Menu):

    def __init__(self):
        wx.Menu.__init__(self)

        # Add some items in the menu
        self.AppendItem(wx.MenuItem(self, wx.NewId(), 'This should be at the'))
        self.AppendItem(wx.MenuItem(self, wx.NewId(), 'insertion point'))
        self.AppendItem(wx.MenuItem(self, wx.NewId(), 'position...'))

# Text area from which to open the custom context menu
class TestTextCtrl(wx.TextCtrl):

    def __init__(self, parent):
        wx.TextCtrl.__init__(self, parent, style=wx.TE_MULTILINE)

        self.parent = parent

        # Set a monospaced font
        font = wx.Font(12, wx.MODERN, wx.NORMAL, wx.NORMAL)
        self.SetFont(font)

        # Get the character size (width and height)
        self.pixelSize = font.GetPixelSize()

        # Display some text
        self.SetValue("[Ctrl] key = custom popup menu \n"
                      "[Menu] key = original context menu \n"
                      "[Ctrl] key = custom popup menu \n"
                      "[Menu] key = original context menu \n"
                      "[Ctrl] key = custom popup menu \n"
                      "[Menu] key = original context menu \n"
                      "[Ctrl] key = custom popup menu \n"
                      "[Menu] key = original context menu \n"
                      "[Menu] key = original context menu \n"
                      "[Ctrl] key = custom popup menu \n"
                      "[Menu] key = original context menu \n"
                      "[Ctrl] key = custom popup menu \n"
                      "[Menu] key = original context menu \n"
                      "[Menu] key = original context menu \n"
                      "[Ctrl] key = custom popup menu \n"
                      "[Menu] key = original context menu \n"
                      "[Ctrl] key = custom popup menu \n"
                      "[Menu] key = original context menu \n"
                      "[Menu] key = original context menu \n"
                      "[Ctrl] key = custom popup menu \n"
                      "[Menu] key = original context menu \n"
                      "[Ctrl] key = custom popup menu \n"
                      "[Menu] key = original context menu \n"
                      "[Menu] key = original context menu \n"
                      "[Ctrl] key = custom popup menu \n"
                      "[Menu] key = original context menu \n"
                      "[Ctrl] key = custom popup menu \n"
                      "[Menu] key = original context menu \n"
                      "[Menu] key = original context menu \n"
                      "[Ctrl] key = custom popup menu \n"
                      "[Menu] key = original context menu \n"
                      "[Ctrl] key = custom popup menu \n"
                      "[Menu] key = original context menu \n"
                      "[Ctrl] key = custom popup menu \n"
                      "[Menu] key = original context menu \n")

        # Activate the [Ctrl] key stroke detection (1/2)
        self.Bind(wx.EVT_KEY_DOWN, self.OnKeyStroke)

    def OnKeyStroke(self, event):

        # Activate the [Ctrl] key stroke detection (2/2)
        if event.GetUnicodeKey() == wx.WXK_CONTROL:

            #######################################
            ##### Here is the interesting code ####
            #######################################

            # Get the scroll position in pixels
            scrollPosition = [
                self.GetScrollPos(wx.HORIZONTAL),
                self.GetScrollPos(wx.VERTICAL),
                ]

            # Get the text cursor position in the text area (int)
            insertionPointPosition = self.GetInsertionPoint()

            # Convert it into a row/column position (2D tuple)
            insertionPointRowColumnPosition = self.PositionToXY(insertionPointPosition)

            # Calculate the popup menu position in pixels
            insertionPointPositionInPixels = []
            for i in range(2):
                insertionPointPositionInPixels.append(
            #       (  row/column position    +   offset   ) * size of character - position of scroll in pixels)
                    (insertionPointRowColumnPosition[i] + i) * self.pixelSize[i] - scrollPosition[i]
                )

            # Convert the position into a wx.Point object
            popupMenuPoint = wx.Point(
                insertionPointPositionInPixels[0],
                insertionPointPositionInPixels[1]
            )

            # Display the context menu at the given position
            self.PopupMenu(CustomMenu(), popupMenuPoint)

            ### We did it ! :) ###

            #######################################
            #######################################
            #######################################

        else:
            event.Skip()

# Test frame
class TestFrame(wx.Frame):

    def __init__(self):
        wx.Frame.__init__(self, None)

        # Create a text area
        TestTextCtrl(self)

        # Display the window
        self.Show(True)


if __name__ == "__main__":

    # Create an application
    application = wx.App(False)

    # Create a frame
    TestFrame()

    # Launch the application
    application.MainLoop()

更新 #1 -> 取自 font.GetPixelSize()

的字符大小

更新 #2 -> 使用 self.GetScrollPos() 获取滚动条的位置

关于python - wx.TextCtrl 中插入点位置的弹出菜单,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26864839/

相关文章:

python - wxPython 系统托盘图标

python - sklearn 中字母的 N 元语法

python - 如何通过i2c发送数组?

javascript - 如何从 $(this).context 获取输入值

java.lang.ClassCastException : android. 部件.ExpandableListView$ExpandableListContextMenuInfo

c++ - 无法在 Netbeans 中使用 WxWIdgets 构建测试应用程序

python - 根据列表从文件名中删除随机文本

python - 如何返回不带引号的字符串 Python 3

c++ - COM IContextMenu::InvokeCommand - 匹配 LPCMINVOKECOMMANDINFO::lpVerb 到项目

python - wxStaticBitmap 与 wxPtyhon 在 GTK+ 不工作