1

wxPython を使用して TextCtrl オブジェクトにカスタム コンテキスト メニューを作成する方法を知っている人はいますか?

ひとまずカスタムメニューを作成できたのですが、[Menu]キーを押したここに画像の説明を入力ときに元のメニューがテキストカーソルの位置に表示されるのに対し、これはマウスカーソルの位置に表示されます。ここに画像の説明を入力ここに画像の説明を入力

4

1 に答える 1

1

わかった、

どういうわけかトリックを行うことができますが、これはのみ機能します

  1. フォントが等幅の場合 (以下のコードを参照)、
  2. フォーカス行に集計文字("\t")がない場合...

簡単に言うと、テキスト カーソルの位置ここに画像の説明を入力を行/列座標に取得し、それらに文字サイズを掛けます。これにより、目的のポップアップ メニューの位置が得られます。

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()

于 2014-11-14T13:40:02.567 に答える