Выделите ListItem в wx.ListCtrl на MouseOver - PullRequest
0 голосов
/ 15 декабря 2011

У меня есть wxListCtrl, который отображает таблицу с информацией (со строками и полями столбцов). Обычно строка будет подсвечена только при нажатии на нее кнопкой мыши. Но я бы хотел выделить его, не нажимая на него. т.е. когда я перемещаю мышь в другую строку, строка будет выделена без щелчка мышью. Возможно ли это?

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

импорт wx

import sys, glob

class MyForm(wx.Frame):

    #----------------------------------------------------------------------
    def __init__(self):
        wx.Frame.__init__(self, None, wx.ID_ANY, "List Control Tutorial")

        # Add a panel so it looks the correct on all platforms
        panel = wx.Panel(self, wx.ID_ANY)
        self.index = 0

    self.list_ctrl = wx.ListCtrl(panel, size=(-1,100),
                     style=wx.LC_REPORT
                     |wx.BORDER_SUNKEN
                     )
    self.list_ctrl.InsertColumn(0, 'Subject')
    self.list_ctrl.InsertColumn(1, 'Due')
    self.list_ctrl.InsertColumn(2, 'Location', width=125)
    self.list_ctrl.Bind(wx.EVT_ENTER_WINDOW, self.onMouseOver)
    self.list_ctrl.Bind(wx.EVT_LEAVE_WINDOW, self.onMouseLeave)

    btn = wx.Button(panel, label="Add Line")
    btn.Bind(wx.EVT_BUTTON, self.add_line)

    sizer = wx.BoxSizer(wx.VERTICAL)
    sizer.Add(self.list_ctrl, 0, wx.ALL|wx.EXPAND, 5)
    sizer.Add(btn, 0, wx.ALL|wx.CENTER, 5)
    panel.SetSizer(sizer)   


    bmp = wx.Image("icon.bmp", wx.BITMAP_TYPE_BMP).ConvertToBitmap()
    il = wx.ImageList(16,16)
    il.Add(bmp)
    self.list_ctrl.AssignImageList(il,wx.IMAGE_LIST_SMALL)      
    line = "Line %s" % self.index


    self.list_ctrl.InsertStringItem(self.index, line,-1)  
    self.list_ctrl.SetStringItem(self.index, 1, "01/19/2010")
    self.list_ctrl.SetStringItem(self.index, 2, "USA")
    self.index += 1     

    self.list_ctrl.InsertStringItem(self.index, line,-1)  
    self.list_ctrl.SetStringItem(self.index, 1, "01/19/2010")
    self.list_ctrl.SetStringItem(self.index, 2, "USA")
    #self.list_ctrl.SetItemBackgroundColour(self.index,wx.LIGHT_GREY)
    self.index += 1 

    self.list_ctrl.InsertStringItem(self.index, line,-1)  
    self.list_ctrl.SetStringItem(self.index, 1, "01/19/2010")
    self.list_ctrl.SetStringItem(self.index, 2, "USA")

    self.index += 1             


#----------------------------------------------------------------------
def add_line(self, event):
    if self.index > 0:
        image = 1
    else:
        image = -1    
    line = "Line %s" % self.index
    self.list_ctrl.InsertStringItem(self.index, line,image)
    self.list_ctrl.SetStringItem(self.index, 1, "01/19/2010")
    self.list_ctrl.SetStringItem(self.index, 2, "USA")
    self.index += 1

def onMouseOver(self, event):
    print "mouse over"
    for item in range(self.list_ctrl.GetItemCount()):
         self.list_ctrl.SetItemBackgroundColour(item,wx.NullColor)
    x = event.GetX()
    y = event.GetY()
    item, flags = self.list_ctrl.HitTest((x, y))
    self.list_ctrl.SetItemBackgroundColour(item,wx.RED)
    #self.list_ctrl.RefreshItems(0,2)
    event.Skip()

def onMouseLeave(self, event):
    print "mouse leave"
    for item in range(self.list_ctrl.GetItemCount()):
         self.list_ctrl.SetItemBackgroundColour(item,wx.NullColor)
    #self.list_ctrl.RefreshItems(0,2)
    event.Skip()
'''         
def onMouseOver(self, event):    #USED to display tooltip on items that cannot be selected

    x = event.GetX()
    y = event.GetY()
    item, flags = self.list_ctrl.HitTest((x, y))
    color = self.list_ctrl.GetItemBackgroundColour(item) 
    if color == wx.NullColor:

        self.list_ctrl.SetItemBackgroundColour(item,wx.RED)
    elif color == wx.RED:
        item = item - 1
        color = self.list_ctrl.GetItemBackgroundColour(item) 
        self.list_ctrl.SetItemBackgroundColour(item,wx.Nu)

'''       
#----------------------------------------------------------------------
# Run the program
if __name__ == "__main__":
    app = wx.App(False)
    frame = MyForm()
    frame.Show()
    app.MainLoop()    

Ответы [ 3 ]

2 голосов
/ 15 декабря 2011

Я бы попытался получить цвет фона одного из ListItems при создании ListCtrl и поместить его в переменную:

self.defaultItemColor = someListItem.GetBackgroundColour()

Тогда используйте это, чтобы изменить цвет назад. После того, как вы вызовете установщик элемента, вам иногда нужно также вызвать метод SetItem (listItem) ListCtrl. По какой-то причине установка фона в NullColour не работает с ListCtrl. Я обнаружил это еще тогда, когда создавал темный режим для одного из моих приложений. Я на самом деле писал об этом здесь: http://www.blog.pythonlibrary.org/2011/11/05/wxpython-creating-a-dark-mode/

0 голосов
/ 09 апреля 2015

Я знаю, что это поздний ответ, но мне подходит следующее: self.listCtrl.Bind (wx.EVT_MOTION, self.onMouseOver) и первоначальная установка self.previous_item в -1

используя его, чтобы выделить строку, наведя на нее курсор мыши, и одновременно изменить подсказку.

def onMouseOver(self, event):
    x = event.GetX()
    y = event.GetY()
    self.item, flags = self.listCtrl.HitTest((x, y))
    if self.item < 0:
        self.listCtrl.SetToolTipString("Colour codes Red - Loaded, Yellow - In Progress, Green - Finished, Blue - Invoiced, White - User defined")
        return
    if self.item != self.previous_item:
        self.old_item = self.previous_item
        self.previous_item = self.item
    else:
        return
    bg_colour = self.listCtrl.GetItemBackgroundColour(self.item) 
    if bg_colour == wx.BLACK or bg_colour == wx.NullColour:
        self.listCtrl.SetItemBackgroundColour(self.item,"#3246A8")
        self.listCtrl.SetItemBackgroundColour(self.old_item,wx.BLACK)
    elif bg_colour == "#3246A8":
        self.listCtrl.SetItemBackgroundColour(self.item,wx.BLACK)
    self.currentItem = self.item
    rowid = self.listCtrl.GetItem(self.currentItem,13)
    stat_test = rowid.GetText()
    rowid = self.listCtrl.GetItem(self.currentItem,1)
    file_test = rowid.GetText()
    rowid = self.listCtrl.GetItem(self.currentItem,4)
    running_test = rowid.GetText()

    if stat_test == "0":
        self.listCtrl.SetToolTipString("File currently playing\nRunning time "+running_test)
    elif stat_test == "1":
        self.listCtrl.SetToolTipString("In Progress\nRunning time "+running_test)
    elif stat_test == "2":
        self.listCtrl.SetToolTipString("Finished\nRunning time "+running_test)
    elif stat_test == "3":
        self.listCtrl.SetToolTipString("Invoiced\nRunning time "+running_test)
    if file_test == self.file_playing and stat_test == "1":
        self.listCtrl.SetToolTipString("File currently playing & In Progress\nRunning time "+running_test)
    if file_test == self.file_playing and stat_test == "2":
        self.listCtrl.SetToolTipString("File currently playing but Finished\nRunning time "+running_test)
    if file_test == self.file_playing and stat_test == "3":
        self.listCtrl.SetToolTipString("File currently playing but Invoiced\nRunning time "+running_test)

Надеюсь, это кому-нибудь поможет

0 голосов
/ 15 декабря 2011

Это не «легко» сделать из коробки, но вы должны быть в состоянии сделать это с небольшим изменением.

Вам нужно будет добавить слушатель событий mouseover и mouseout к вашему объекту wxListCtrl, а затем проверять, какой элемент поражается каждый раз, когда вы получаете событие mouseover. Возможно, вы сможете кэшировать координаты элементов списка, но прокрутка списков и изменение размеров окон может создать проблему, если вы пойдете по этому пути.

Некоторый код для начала работы (не тестировался, возможно, не будет работать, и вам нужно добавить MyListCtrl в подходящий wx.Frame):

import wx

class MyListCtrl(wx.ListCtrl):
    def __init__(self, parent, id):
        wx.ListCtrl.__init__(self, parent, id)
        self.Bind(wx.EVT_ENTER_WINDOW, self.onMouseOver)
        self.Bind(wx.EVT_LEAVE_WINDOW, self.onMouseLeave)

    def onMouseOver(self, event):
        #Loop through all items and set bgcolor to default, then:
        item = self.HitTest(event.GetPosition())
        self.SetItemBackgroundColour(item, 'Green')
        self.RefreshItems()
        event.Skip()

    def onMouseLeave(self, event):
        #Loop through all items and set bgcolor to default, then:
        self.RefreshItems()
        event.Skip()
...