I am using Ultimatelistctrl on windows. Once I select an item the up/down keys step through the list nicely.
But as soon as I add or remove an item the up/down keys stop moving though the list and simply move the scroll bar. I have to physically click on the listctrl to restore the behaviour I want. How/why?
Thanks.
Without any sample code to demonstrate what you are doing, it’s difficult to know what exactly is happening.
The up/down arrow keys work when there is a selected item in list control and the list control has the keyboard focus. If you use a button to add or delete items, the selection in the list control is lost and the keyboard focus switches to the button that was pressed.
One possible way around this is to have the buttons’ event handlers select an appropriate entry in the list control and then give the control the keyboard focus. The up/down arrow keys should then resume working.
Here is some hacked code which demonstrates a simple example with an UltimateListCtrl using a REPORT view in single selection mode (it has only been tested on Python 3.8.5 + wxPython 4.1.1 gtk3 (phoenix) wxWidgets 3.1.5 + Linux Mint 20.1).
import sys
import wx
from wx.lib.agw import ultimatelistctrl as ULC
class MyFrame(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, None, wx.ID_ANY, "ULC + Arrow Keys", size=(300, 300))
main_sizer = wx.BoxSizer(wx.VERTICAL)
agw_style = ULC.ULC_REPORT | ULC.ULC_SINGLE_SEL | ULC.ULC_HRULES | wx.LC_VRULES
self.ulc = ULC.UltimateListCtrl(self, wx.ID_ANY, agwStyle=agw_style)
main_sizer.Add(self.ulc, 1, wx.ALL | wx.EXPAND, 8)
add_button = wx.Button(self, wx.ID_ANY, "Add")
main_sizer.Add(add_button, 0, 0, 0)
del_button = wx.Button(self, wx.ID_ANY, "Delete")
main_sizer.Add(del_button, 0, 0, 0)
self.SetSizer(main_sizer)
self.Layout()
self.Bind(wx.EVT_BUTTON, self.OnAdd, add_button)
self.Bind(wx.EVT_BUTTON, self.OnDelete, del_button)
self.ulc.InsertColumn(0, "Item", width=130)
self.ulc.InsertColumn(1, "Number", format=ULC.ULC_FORMAT_RIGHT, width=60)
for i in range(5):
name = "Item %d" % i
index = self.ulc.InsertStringItem(sys.maxsize, name)
self.ulc.SetStringItem(index, 1, str(i))
self.last = self.ulc.GetItemCount() - 1
def OnAdd(self, e):
self.last += 1
name = "New Item %d" % self.last
self.ulc.Append((name, str(self.last)))
index = self.ulc.GetItemCount() - 1
self.ulc.EnsureVisible(index)
self.ulc.Select(index)
self.ulc.SetFocus()
def OnDelete(self, e):
index = self.ulc.GetFirstSelected()
if index != wx.NOT_FOUND:
self.ulc.DeleteItem(index)
index = min(index, self.ulc.GetItemCount() - 1)
if index >= 0:
self.ulc.Select(index)
self.ulc.SetFocus()
if __name__ == "__main__":
app = wx.App()
frame = MyFrame().Show()
app.MainLoop()
My list takes data from a list of dictionaries. When this list is modified it has to be reloaded in ULC.
Once reloaded I use: self.ulc.Select(index) and self.ulc.SetFocus() to highlight the recently changed entry.
If I now press the up/down keys they move the scrollbar until I manually click on the item, then the keys will highlight items in the list. I want to avoid this click!
I always want the up/down keys to move through the list, never to move the scrollbar…