我是wxPython的新手,所以请保持温和。
我正在尝试进行虚拟列表控制,当用户按下鼠标右键时,该控件将通过上下文菜单弹出控制。
从我的一点经验来看,似乎虚拟列表控件喜欢使用“item”(读取:“row”)和“column”数字进行操作。很公平。
当我收到右键单击事件时,我可以通过调用event.GetIndex()来轻松获得行(项)编号。但是如何获取被点击的对象的列号?
import wx
import wx.lib.agw.ultimatelistctrl as ULC
class MyFrame(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, None, wx.ID_ANY, "Right-click example")
self.list = MyListCtrl(parent=self)
sizer = wx.BoxSizer(wx.VERTICAL)
sizer.Add(self.list, 1, wx.EXPAND)
self.SetSizer(sizer)
class MyListCtrl(ULC.UltimateListCtrl):
def __init__(self, parent, *args, **kwargs):
ULC.UltimateListCtrl.__init__(self, parent, 1, agwStyle=wx.LC_REPORT|wx.LC_VIRTUAL|wx.LC_HRULES|wx.LC_VRULES)
self.InsertColumn(0, "Column0")
self.InsertColumn(1, "Column1")
self.SetItemCount(5)
# Bindings
self.Bind(ULC.EVT_LIST_ITEM_RIGHT_CLICK, self.OnRightClick)
def OnGetItemText(self, item, column):
return "%d, %d" % (item, column)
def OnGetItemToolTip(self, item, column):
pass
def OnGetItemTextColour(self, item, column):
pass
def OnRightClick(self, event):
# Get the index (i.e. which row was clicked)
print("OnColRightClick: GetIndex = %r\n" %(event.GetIndex()))
# How can I get which column was clicked?
if __name__ == "__main__":
# Start the GUI
app = wx.App()
frame = MyFrame()
app.SetTopWindow(frame)
frame.Show()
app.MainLoop()
答案 0 :(得分:1)
“如果一开始你没有成功,请再试一次。 然后退出;对此毫无用处。“ - 马克吐温
我很尴尬地承认我浪费了一周的时间。为了避免其他人陷入同样的陷阱,让我简化一下:
如果你有一个事物列表,其中每个东西都有你想要一起显示但又乐于作为一组操作的子元素,那么ListCtrl可能适合你。
如果你有一个事物列表,其中每个东西都有子元素,但你有兴趣独立操作这些子元素,ListCtrl似乎不是你想要的。< / p>
我已经开始使用Grid小部件,到目前为止它似乎正在为我的目的而工作。这可能会在稍后再次让我感到困惑,但现在似乎有效。以下是来自Wx Huge Grid演示的一些略微修改的代码,用于说明网格小部件上的点击将如何返回行和列“地址”。
如果有人有关于如何从ListCtrl获取列号的建议,我当然都是耳朵。
import wx
import wx.grid as gridlib
#---------------------------------------------------------------------------
class HugeTable(gridlib.PyGridTableBase):
def __init__(self, log):
gridlib.PyGridTableBase.__init__(self)
self.log = log
self.odd=gridlib.GridCellAttr()
self.odd.SetBackgroundColour("sky blue")
self.even=gridlib.GridCellAttr()
self.even.SetBackgroundColour("sea green")
def GetAttr(self, row, col, kind):
attr = [self.even, self.odd][row % 2]
attr.IncRef()
return attr
# This is all it takes to make a custom data table to plug into a
# wxGrid. There are many more methods that can be overridden, but
# the ones shown below are the required ones. This table simply
# provides strings containing the row and column values.
def GetNumberRows(self):
return 10000
def GetNumberCols(self):
return 10000
def IsEmptyCell(self, row, col):
return False
def GetValue(self, row, col):
return str( (row, col) )
def SetValue(self, row, col, value):
self.log.write('SetValue(%d, %d, "%s") ignored.\n' % (row, col, value))
#---------------------------------------------------------------------------
class HugeTableGrid(gridlib.Grid):
def __init__(self, parent, log):
gridlib.Grid.__init__(self, parent, -1)
table = HugeTable(log)
# The second parameter means that the grid is to take ownership of the
# table and will destroy it when done. Otherwise you would need to keep
# a reference to it and call it's Destroy method later.
self.SetTable(table, True)
self.Bind(gridlib.EVT_GRID_CELL_RIGHT_CLICK, self.OnCellRightClick)
def OnCellRightClick(self, event):
print "OnCellRightClick: (%d,%d)\n" % (event.GetRow(), event.GetCol())
#---------------------------------------------------------------------------
class TestFrame(wx.Frame):
def __init__(self, parent, log):
wx.Frame.__init__(self, parent, -1, "Huge (virtual) Table Demo", size=(640,480))
grid = HugeTableGrid(self, log)
grid.SetReadOnly(5,5, True)
#---------------------------------------------------------------------------
if __name__ == '__main__':
import sys
app = wx.App()
frame = TestFrame(None, sys.stdout)
frame.Show(True)
app.MainLoop()
答案 1 :(得分:1)
遗憾的是,没有一种获取列信息的好方法。我确实在这个问题上找到了这个讨论:http://wxpython-users.1045709.n5.nabble.com/Getting-row-col-of-selected-cell-in-ListCtrl-td2360831.html
听起来你必须自己计算一下。根据Robin的说法,wx.lib.mixins.listctrl.TextEditMixin中有一些代码可能有所帮助。我还发现ObjectListView(ListCtrl的包装器)的配方也可能有所帮助:http://code.activestate.com/recipes/577543-objectlistview-getcolumnclickedevent-handler/
答案 2 :(得分:1)
我不知道在点击一行时是否可以在listctrl中获取列号(因为它选择整行,而不是单个单元格)...但是,如果您想要单击列时的列号在列上(就像我做的那样,在很多搜索结束之后)你可以将一个事件(wx.EVT_LIST_COL_CLICK / wx.EVT_LIST_COL_RIGHT_CLICK)绑定到listctrl,并在事件方法中使用event.m_col ...它存储列号码
self.Bind(wx.EVT_LIST_COL_CLICK, self.onColumnClick, self.myListCtrl)
...
def onColumnClick(self, evt):
column_clicked = evt.m_col
从这里获得灵感:http://wxpython.org/Phoenix/docs/html/ListCtrl.html,在“此课程发布的活动”部分
答案 3 :(得分:1)
这在 listctrl 中对我有用。它并不完美,但它有效。 唯一的限制是我们要选择的左侧的所有列都必须可见。
self.Bind(wx.EVT_LEFT_DCLICK, self.OnDoubleClick)
self.col=-1
....
def OnDoubleClick(self, event):
posx=event.GetX()
self.col=-1
while posx>0:
self.col+=1
posx=posx-self.GetColumnWidth(self.col)
event.Skip()
答案 4 :(得分:0)
这适用于网格,可能很容易适应ListCtrl:
def onclick(self,event):
rows = cumsum(self.GetRowSize(i) for i in range(self.GetNumberRows()))
cols = cumsum(self.GetColSize(i) for i in range(self.GetNumberCols()))
irow = self.GetNumberRows() - sum(event.m_y < y for y in rows)
icol = self.GetNumberCols() - sum(event.m_x < x for x in cols)
print irow,icol
答案 5 :(得分:0)
您可以使用EVT_LIST_COL_CLICK或EVT_LIST_COL_RIGHT_CLICK事件处理程序中的event.GetColumn()。这将返回m_col值。