I am trying to filter an objectlistview based on a text value in a certain column of my data. I can't figure out how to construct the filter properly. I have been refering to:
http://objectlistview.sourceforge.net/python/features.html
http://objectlistview.sourceforge.net/python/majorClasses.html
I am able to get Filter.Head(n) to work sucessfully but not ableto get Filter.TextSearch(objectListView, columns=(), text="") to work because I don't understand what the parameter types are suppost to be.
I have written the below code:
def OnFilterMeter(self,event):
list = self.exception_panel.col_list ## The lenght of my column list
col = list[len(list)-1] ## I want to search the last column
meter_flt = Filter.TextSearch(self.exception_panel,columns = (col), text = "10") ## Create filter to find string 10 in last column
self.exception_panel.SetFilter(meter_flt)
self.exception_panel.populate()
I can't understand why this doesn't work. The program doesn't filter the list when it tries to populate the list view again. At the very least it should show all blanks because it cannot find any items that are equal to "10". Please help. Thank you
Below is my code :
class Display_Manager(wx.Frame):
def __init__(self, parent, id, title):
wx.Frame.__init__(self, parent, -1, title)
self.exception_panel = Exception_Display(self,0)
# self.exception_panel2 = Exception_Display(self,1)
## Setup FileMenu Bar Setup
filemenu= wx.Menu() ## Create Menu Bar
filemenu.Append(ID_LOG,"Login","Login as user with password.") ## Clicking shoudl load a single dailyi report which user selects
filemenu.Append(ID_LOAD,"Load Report","Load Daliy Exception Report") ## Clicking shoudl load a single dailyi report which user selects
filemenu.Append(ID_LOADS,"Load All","Load All Daliy Exception Reports") ## Clicking should load all daily reports in a directory which user selects
filemenu.Append(ID_REFRESH,"Refresh DB","Refresh Database. Overwrites any un saved data.") ## Clicking should refreseh the database and overwrite any unsaved changes
filemenu.Append(ID_SAVE,"Save DB","Saves and commits any changes to database.") ## Clicking will save and commit any changes or new data to the database
filemenu.Append(ID_EXIT,"E&xit"," Terminate the program") ## exit the program
## Setup Edit Menu Bar
editmenu = wx.Menu()
editmenu.Append(ID_ADD,"Add","Add Exception")
editmenu.Append(ID_DELETE,"Delete","Delete Exception")
editmenu.Append(ID_UNDO,"Stepback DB","Go back to a previous version of the database")
editmenu.Append(ID_REDO,"Stepfoward DB","Go foward to a previous version of the database")
## Setup Report Menu
reportmenu = wx.Menu()
reportmenu.Append(ID_REPORT,"Exception Report","Generate an Excel Report of selected exceptions.")
reportmenu.Append(ID_REPORT2,"Meter Report","Generate an Excel Report of selected exceptions.")
reportmenu.Append(ID_REPORT3,"Transformer Report","Generate an Excel Report of selected exceptions.")
## Setup Bucket Menu
bucketmenu = wx.Menu()
bucketmenu.Append(ID_METERPROB,"Meter Problem","Place the meter in the meter problem bucket.")
bucketmenu.Append(ID_LOWVOLT,"Investigate Low Voltage","Place the meter in the investigate bucket.")
bucketmenu.Append(ID_TURNS,"Turns Ratio","Place the meter in the turns ratio bucket.")
## Setup Configure Menu Menu
configmenu = wx.Menu()
configmenu.Append(ID_FILTER,"Set Filters","Filter by district and company.")
configmenu.Append(ID_SAVEFIL,"Save Filters","Save Filters for Later use.")
configmenu.Append(ID_LOADFIL,"Load Filters","Load Filters for Later use.")
## Add file menu bar
menuBar = wx.MenuBar()
menuBar.Append(filemenu,"&File")
menuBar.Append(editmenu, "&Edit")
menuBar.Append(reportmenu, "&Reports")
menuBar.Append(configmenu, "&Config")
menuBar.Append(bucketmenu, "&Bucket")
self.SetMenuBar(menuBar)
## Create Toolbar
tb = self.CreateToolBar( wx.TB_HORIZONTAL | wx.NO_BORDER |
wx.TB_FLAT | wx.TB_TEXT)
tb.AddSimpleTool(10, wx.Bitmap('images/database.png'), 'Save Database')
tb.AddSimpleTool(20, wx.Bitmap('images/excel.png'), 'Get Quick Excel Report')
tb.AddSimpleTool(70, wx.Bitmap('images/analyze.png'), 'Analyze Selected Exceptions')
tb.AddSimpleTool(71, wx.Bitmap('images/refresh.png'), 'Refresh Selected Relationships')
tb.AddSeparator()
tb.AddSimpleTool(30, wx.Bitmap('images/today.png'), 'Filter only the latest data.')
tb.AddSimpleTool(40, wx.Bitmap('images/all_time.png'), 'Filter All Data from all time')
tb.AddSimpleTool(41, wx.Bitmap('images/date_range.png'), 'Select a date range to view data over')
tb.AddSeparator()
tb.AddSimpleTool(50, wx.Bitmap('images/AMI_Meter.png'), 'Bucket as meter problem')
tb.AddSimpleTool(60, wx.Bitmap('images/violation.png'), 'Bucket to District')
tb.AddSimpleTool(61, wx.Bitmap('images/turns.png'), 'Bucket Turns Ratio')
tb.AddSimpleTool(62, wx.Bitmap('images/plan.png'), 'Bucket for further review for planning engineer')
tb.AddSeparator()
tb.AddSimpleTool(63, wx.Bitmap('images/cyme.png'), 'Load CYME model for specific meter')
tb.AddSimpleTool(64, wx.Bitmap('images/relate_dot.png'), 'Cluster & Relate Meter Exceptions')
tb.AddSeparator()
tb.AddSimpleTool(65, wx.Bitmap('images/bucket_m.png'), 'Filter Meter Bucket')
tb.AddSimpleTool(66, wx.Bitmap('images/bucket_v.png'), 'Filter Violation Bucket')
tb.AddSimpleTool(67, wx.Bitmap('images/bucket_t.png'), 'Filter Turns Ratio Bucket')
tb.AddSimpleTool(68, wx.Bitmap('images/bucket_p.png'), 'Filter Planning Bucket')
tb.SetToolBitmapSize((84,84))
tb.Realize()
self.Bind(wx.EVT_TOOL,self.OnRefresh,id =71)
self.Bind(wx.EVT_TOOL,self.OnAnalyze,id =70)
self.Bind(wx.EVT_TOOL,self.OnSave,id =10)
self.Bind(wx.EVT_TOOL,self.OnBucketMeter,id =50)
self.Bind(wx.EVT_TOOL,self.OnVioMeter,id =60)
self.Bind(wx.EVT_TOOL,self.OnTurnsMeter,id =61)
self.Bind(wx.EVT_TOOL,self.OnPlanMeter,id =62)
self.Bind(wx.EVT_TOOL,self.OnFilterMeter,id =65)
# self.Bind(wx.EVT_TOOL,self.OnFilterMeter,id =66)
# self.Bind(wx.EVT_TOOL,self.OnFilterMeter,id =67)
# self.Bind(wx.EVT_TOOL,self.OnFilterMeter,id =68)
## Create Sizers
# self.main_sizer = wx.BoxSizer(wx.VERTICAL)
# self.top_sizer = wx.BoxSizer(wx.HORIZONTAL)
# self.bottom_sizer = wx.BoxSizer(wx.HORIZONTAL)
# self.main_sizer.Add(self.top_sizer,0,wx.EXPAND)
# self.main_sizer.Add(self.bottom_sizer,0,wx.EXPAND)
## Show the frame
# self.SetSizer(self.main_sizer)
self.Center()
self.Show(True)
def OnSave(self,event):
session.commit()
print "ON Save"
def OnRefresh(self,event):
self.exception_panel.populate()
self.ColorBuckets()
print "OnRelate"
def OnAnalyze(self,event):
objectList = self.exception_panel.GetSelectedObjects() ## Get list of selected objects to relate in the database
for object in objectList:
print object
object.calculate()
# print self.GetValueAt(self.GetObjectAt(event.rowIndex),event.subItemIndex)
# self.temp_value = event.editor.GetValue()
self.exception_panel.populate()
print "OnAnalze"
def OnFilterDate1(self,event):
print "on Filter date"
def OnFilterDate2(self,event):
print "on Filter date"
def OnFilterDate3(self,event):
print "on Filter date"
def OnFilterMeter(self,event):
list = self.exception_panel.col_list
col = list[len(list)-1]
# meter_flt = Filter.Head(10)
meter_flt = Filter.TextSearch(self.exception_panel,columns = (col), text = "10")
self.exception_panel.SetFilter(meter_flt)
self.exception_panel.populate()
# self.exception_panel.Refresh()
# self.exception_panel.populate()
# self.exception_panel.SetObjects(qrty_meters_excpt)
# self.exception_panel.populate()
print "On Filter Meter"
def OnBucketMeter(self,event):
objectList = self.exception_panel.GetSelectedObjects()
for object in objectList:
print object
object.known_flags = 20 ## Meter Mismatch Flag Known ***ffa500
self.exception_panel.populate()
self.ColorBuckets()
def OnVioMeter(self,event):
objectList = self.exception_panel.GetSelectedObjects()
for object in objectList:
object.known_flags = 10 ## Meter Mismatch Flag Known ***ffa500
self.exception_panel.populate()
self.ColorBuckets()
def OnTurnsMeter(self,event):
objectList = self.exception_panel.GetSelectedObjects()
for object in objectList:
object.known_flags = 30 ## Meter Mismatch Flag Known ***ffa500
self.exception_panel.populate()
self.ColorBuckets()
def OnPlanMeter(self,event):
objectList = self.exception_panel.GetSelectedObjects()
for object in objectList:
object.known_flags = 40 ## Meter Mismatch Flag Known ***ffa500
self.exception_panel.populate()
self.ColorBuckets()
def ColorBuckets(self): ## Color All Buckets according to knowflags
## Query the session for only items that have know_flags greate than 0
qrty_color_buckets = session.query(Exception).filter(Exception.known_flags != "").all()
print qrty_color_buckets
for exception in qrty_color_buckets:
print exception.known_flags == 10
flag = int(exception.known_flags) ## alias the flag
if flag == 20: ## Meter Mismatch
self.exception_panel.SetItemBackgroundColour(self.exception_panel.GetIndexOf(exception),'#ffa500') ## Oranage
elif flag == 10: ## Violation
self.exception_panel.SetItemBackgroundColour(self.exception_panel.GetIndexOf(exception),'#ff0000') ## Red
elif flag == 30: ## Turns Ratio
self.exception_panel.SetItemBackgroundColour(self.exception_panel.GetIndexOf(exception),'#0066CC') ## Blue
elif flag == 40: ## Plan referal
self.exception_panel.SetItemBackgroundColour(self.exception_panel.GetIndexOf(exception),'#FFFF00') ## Yellow
Please see the function OnFilterMeter.
The following works for me, it does a search on the second column and it shows just one matching entry.
# -*- coding: utf-8 -*-
import datetime
import wx
import wx.lib.sized_controls as SC
import ObjectListView as OLV
class MyData:
def __init__(self, year, month, day, level, sets, reps):
self.date = datetime.date(year, month, day)
self.level = level
self.sets = sets
self.reps = reps
def GetDate(self):
return self.date
def GetLevel(self):
return self.level
def GetSets(self):
return self.sets
def GetRepetitions(self):
return self.reps
class MyListCtrl(OLV.GroupListView):
def __init__(self, parent):
super(MyListCtrl, self).__init__(parent, wx.ID_ANY, style=wx.LC_REPORT)
self.SetColumns(self._ColumnDefinitions())
meter_flt = OLV.Filter.TextSearch(self, columns=self.columns[2:3],
text="7")
self.SetFilter(meter_flt)
self.SetObjects(self._DataObjects())
def _DataObjects(self):
return [MyData(2010,10,8, 1, 2, 3),
MyData(2005,10,10, 7, 2, 3),
MyData(2010,10,3, 2, 2, 3),
MyData(2012,10,10, 1, 2, 3),
MyData(2014,10,10, 1, 2, 3)
]
def _ColumnDefinitions(self):
return [OLV.ColumnDefn('Date', valueGetter='GetDate', groupKeyGetter='GetDate'),
OLV.ColumnDefn('Level', valueGetter='GetLevel', width=150),
OLV.ColumnDefn('Sets', valueGetter='GetSets', width=100, groupKeyGetter='GetSets'),
OLV.ColumnDefn('Reps', valueGetter='GetRepetitions', width=200)]
class MyFrame(SC.SizedFrame):
def __init__(self):
super(MyFrame, self).__init__(None)
pane = self.GetContentsPane()
olv = MyListCtrl(pane)
olv.SetSizerProps(expand=True, proportion=1)
if __name__ == '__main__':
import wx.lib.mixins.inspection as WIT
app = WIT.InspectableApp()
win = MyFrame()
win.Show()
app.MainLoop()
Related
Alrighty, so I have 3 total functions defined in the project, but when I use the delete command, it will not refresh the other function to show the update to the rows, but when I use the submit command it does refresh. Any Advice? Main goal is that first my_delete(), I included the submit() as that one is correctly updating the show().
Little function to clearly pull information from the database for active trades, seperating the proper information to the columns and rows
def my_delete(self,id):
my_var=tkinter.messagebox.askyesnocancel("DELETE?", "Delete id:"+str(id),icon='warning',default="no")
if my_var:
r_set=c.execute("DELETE FROM openPositions WHERE s_id=" + str(id) )
conn.commit()
tkinter.messagebox.showerror("Deleted ","No of records deleted=" +str(r_set.rowcount))
self.show()
def show(self):
r_set=c.execute("SELECT * FROM openPositions")
i=6
for openPositions in r_set:
for j in range(len(openPositions)):
e = Label(self.master, width=10, text=(openPositions[j]), font=("Helvetica", 12))
e.grid(row=i, column = j + 1, padx=(70,0), pady=(5,0), columnspan=1)
### Close position button to populate for every trade ###
e = Button(self.master, text="Close Position", width=30, command=lambda d=openPositions[0] : self.my_delete(d))
e.grid(row=i, column = 6, padx=(10,0), pady=(5,0), columnspan=3)
i=i+1 # increments for each to next row
### Function for when Button is Pressed ###
def submit(self):
### convert string values to a new variable ##
stk = self.varStk.get()
typ = self.varType.get()
## changing quan and etrPr from string to integer and float values for multiplication ##
quan = int(self.varQuan.get())
entPr = float(self.varEnPr.get())
## multiplying quan and entPr to give us the Position Size for database and submitted text ##
posSize = quan * entPr
## Clearing entered data and resetting drop down menu to buy once button is clicked ##
self.txtStkTik.delete(0, END)
self.txtpos_quan.delete(0, END)
self.txtpos_price.delete(0, END)
self.varType.set("Buy")
## setting variables into an array for easy submitting to database ##
array1 = [stk,typ,quan,entPr,posSize]
## connecto to database and inserting array of variables into database ##
conn.executemany('INSERT INTO openPositions(stock_ticker, entryType, pos_quan, entryPrice, pos_size) VALUES (?,?,?,?,?)', (array1,))
conn.commit()
## pop up message displaying that commit of stock was completed ##
tkinter.messagebox.showinfo("Trade Submitted.", "You submitted {} for {} order in amount of {} share at an entry price of ${} for a total Position Size of ${}".format(stk,typ,quan,entPr,posSize))
#### Copied over the function for writing the information on screen to auto populate info when clicking submit instead of refreshing the app ###
self.show()
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 3 years ago.
Improve this question
With this application, I tried to create 2 variants of the QListView view and apply different ways of working with it. The first option involves a list without Checkboxes, where the user can select several items while holding down the CTRL key:Variant 1. The second option differs visually from the first - checkboxes are present, and the selection process is also different (you do not need to use CTRL, and clicking on a specific position first selects it and then deselects it)Variant 1.
#!/usr/bin/python
# coding=utf-8
headline = """
###############################################################################
# Program #
# a small ListView application in PyQt5 (Python 3.7) #
###############################################################################
All comments are in two languages (Russian, English)
Все комментарии на двух языках (русский, английский)
"""
import sys
import random
from PyQt5 import QtWidgets, QtGui, QtCore, Qt
class HelloApplication(QtWidgets.QApplication):
def __init__(self, args):
"""
In the constructor, we do everything that is necessary to run our application, which
creates a QApplication in the __init__ method, then adds our widgets and finally
runs exec_loop
В конструкторе мы делаем всё, что необходимо для запуска нашего приложения, которое
создаёт QApplication в __init__ методе, затем добавляет наши виджеты и, наконец,
запускает exec_loop
"""
QtWidgets.QApplication.__init__(self,args)
self.addWidgets()
def addWidgets(self):
# Create widgets
# Создание виджетов
self.checkCalc=0
self.StartList=[]
self.BaseWidget=QtWidgets.QWidget()
self.BaseWidget.setWindowTitle('Example List')
self.grid = QtWidgets.QGridLayout()
self.verCombo = QtWidgets.QComboBox()
self.listView=QtWidgets.QListView()
self.listViewmodel = QtGui.QStandardItemModel(self.listView)
self.listView.setModel(self.listViewmodel)
# Setting options for widgets (placement, size)
# Установка параметров для виджетов (размещение, размеры)
self.listView.setModelColumn(2)
self.grid.addWidget(self.verCombo,0,0,1,3)
self.grid.addWidget(self.listView, 2, 0, 3, 3)
# Setting actions for widgets
# Установка действий для виджетов
self.listView.clicked[QtCore.QModelIndex].connect(self.on_clicked)
self.verCombo.activated[str].connect(self.onverComboActivated)
# Setting statuses, texts, etc. for widgets at start
# Установка статусов, текстов и прочего для виджетов на старте
self.verCombo.addItem("1 - NO CKECKBOXES")
self.verCombo.addItem("2 - WITH CKECKBOXES")
self.verCombo.setCurrentIndex(0)
# This piece of code determines whether multiple items can be selected on a ListView.
# Этот кусочек кода определяет, можно ли выбирать несколько элементов на ListView.
if self.verCombo.currentIndex() + 1 == 1:
self.listView.setSelectionMode(
QtWidgets.QAbstractItemView.ExtendedSelection
)
#self.show_hide_ckeckinlistView(FType=1)
else:
self.listView.setSelectionMode(
QtWidgets.QAbstractItemView.SingleSelection
)
self.addrowinlistView(
'Cookie dough', # Must be store-bought
'Hummus', # Must be homemade
'Spaghetti', # Must be saucy
'Dal makhani', # Must be spicy
'Chocolate whipped cream' # Must be plentiful
)
self.BaseWidget.setLayout(self.grid)
chechAllSelected_resulr1, chechAllSelected_resulr2, chechAllSelected_resulr3, chechAllSelected_resulr4 = self.chechAllSelected()
self.BaseWidget.show()
# Procedure for determining those items that are highlighted
# The procedure should work both in the situation of the list with checkmarks, and without them
# Процедура для определения тех элементов, которые выделены
# Процедура должна работать как в ситуации списка с галочками, так и без них
def chechAllSelected (self):
SelectedList=[]
list_of_indexes_selectedLayers=[]
list_of_texts_selectedLayers=[]
Items_list=[]
#item = self.listView.itemFromIndex()
selectedLayers = self.listView.selectedIndexes()
# CUT FOR A SHEET WITHOUT TYPES
# ОТЛАВЛИВАЕМ ДЛЯ ЛИСТА БЕЗ ГАЛОЧЕК
if self.verCombo.currentIndex()+1==1:
print ("Here when checking")
for i in selectedLayers:
item = self.listViewmodel.itemFromIndex(i)
Items_list.append(item)
list_of_indexes_selectedLayers.append(item.index().row())
list_of_indexes_selectedLayers.sort()
for i in range(len(list_of_indexes_selectedLayers)):
SelectedList.append(int(list_of_indexes_selectedLayers[i]))
item = self.listViewmodel.itemFromIndex(
self.listViewmodel.index(int(list_of_indexes_selectedLayers[i]), 0))
list_of_texts_selectedLayers.append(item.text())
print("List: ", list_of_indexes_selectedLayers, " ", list_of_texts_selectedLayers, " ", Items_list)
# CUT FOR A SHEET WITH TIPS
# ОТЛАВЛИВАЕМ ДЛЯ ЛИСТА С ГАЛОЧКАМИ
else:
for i in range(self.listViewmodel.rowCount()):
if self.listViewmodel.item(i).checkState():
SelectedList.append(i)
if len(SelectedList)==0: res_chechAllSelected=0
if 0<len(SelectedList)<self.listViewmodel.rowCount(): res_chechAllSelected=1
if 0<len(SelectedList) == self.listViewmodel.rowCount(): res_chechAllSelected = 2
print ("In chechAllSelected:", len(SelectedList)," ", self.listViewmodel.rowCount()," ", res_chechAllSelected, " ", SelectedList)
return len(SelectedList), self.listViewmodel.rowCount(), res_chechAllSelected, SelectedList
# Function for entering values in ListView (any values, lists)
# Функция ввода значений в ListView (любые значения, списки)
def addrowinlistView(self,*rowsforadd):
for i in rowsforadd:
# Create an item with a caption
item = QtGui.QStandardItem(i)
# Add a checkbox to it
#item.setCheckState(True)
# generate a list for random selection
# генерируем список для случайного выбора
Chous_for_random = [0, 2]
if self.verCombo.currentIndex() + 1 == 1:
#print("индекс переключателя: ",self.verCombo.currentIndex() + 1)
# whether to tick the item
# ставить ли галочку около элемента
item.setCheckable(False)
self.listViewmodel.appendRow(item)
if random.choice(Chous_for_random)==2:
index = self.listViewmodel.indexFromItem(item)
sm = self.listView.selectionModel()
sm.select(index, QtCore.QItemSelectionModel.Select)
else:
# whether to tick the item
# ставить ли галочку около элемента
item.setCheckable(True)
# set the status depending on the selected number
# ставим статус в зависимости от выбранного числа
item.setCheckState(random.choice(Chous_for_random))
self.listViewmodel.appendRow(item)
# Add the item to the model
# Добавляем элемент в модель
#self.listViewmodel.appendRow(item)
#self.BaseWidget.listViewmodel.appendRow(item)
def on_clicked(self, index):
item = self.listViewmodel.itemFromIndex(index)
myitem=QtWidgets.QListWidgetItem()
#print (("on_clicked: itemIndex='{}', itemText='{}'"
# .format(item.index().row(), item.text())))
if self.verCombo.currentIndex()+1==1:
# print(item.index().row())
pass
else:
print("""This position: """, int(item.index().row()))
chechAllSelected_resulr1, chechAllSelected_resulr2, chechAllSelected_resulr3, chechAllSelected_resulr4 = self.chechAllSelected()
self.StartList = chechAllSelected_resulr4
if self.listViewmodel.item(item.index().row()).checkState():
item.setCheckState(0)
self.StartList.remove(item.index().row())
else:
item.setCheckState(2)
self.StartList.append(item.index().row())
print("Here")
chechAllSelected_resulr1, chechAllSelected_resulr2, chechAllSelected_resulr3, chechAllSelected_resulr4 = self.chechAllSelected()
#print("Here")
#self.on_chechBox_click(FType=False, FClick=0, FStatus=chechAllSelected_resulr3)
#self.chechAllSelected()
#self.listViewmodel.removeRow(item.index().row())
# mode switching (with / without checkmarks) with the removal of the function to remove / show checkmarks
# перевлючение режима (с галочками / без) с вывозом функции убрать / показать галочки
def onverComboActivated(self, text):
self.verCombo.setCurrentText(text)
len_SelectedList, listViewmodel_rowCount, res_chechAllSelected, SelectedLis = self.chechAllSelected()
print ("This point: ", len_SelectedList," ", listViewmodel_rowCount," ", res_chechAllSelected," ", SelectedLis)
self.show_hide_ckeckinlistView(
self.verCombo.currentIndex(),
listViewmodel_rowCount,
SelectedLis
)
print(self.verCombo.currentText())
# print(self.verCombo.currentText()," индекс = ", self.verCombo.currentIndex())
# self.chechAllSelected ()
if __name__ == "__main__":
app = HelloApplication(sys.argv)
sys.exit(app.exec_())
QAbstractItemView Class
selectionMode : SelectionMode
This property holds which selection mode the view operates in
This property controls whether the user can select one or many items and, in many-item selections,
whether the selection must be a continuous range of items.
QAbstractItemView::ExtendedSelection
When the user selects an item in the usual way, the selection is cleared and the new item selected.
However, if the user presses the Ctrl key when clicking on an item, the clicked item gets toggled
and all other items are left untouched. If the user presses the Shift key while clicking on an item,
all items between the current item and the clicked item are selected or unselected, depending
on the state of the clicked item. Multiple items can be selected by dragging the mouse over them.
Try it:
headline = """
###############################################################################
# Program #
# a small ListView application in PyQt #
###############################################################################
"""
import sys
import random
from PyQt5 import QtWidgets, QtGui, QtCore # , Qt
class HelloApplication(QtWidgets.QWidget): #QApplication):
def __init__(self):
super().__init__()
self.addWidgets()
def addWidgets(self):
self.checkCalc = 0
self.StartList = []
# self.BaseWidget = QtWidgets.QWidget()
self.setWindowTitle('Example List')
self.grid = QtWidgets.QGridLayout()
self.verCombo = QtWidgets.QComboBox()
self.listView = QtWidgets.QListView()
# +++
self.listView.setSelectionMode(QtWidgets.QAbstractItemView.ExtendedSelection) # +++
self.listViewmodel = QtGui.QStandardItemModel(self.listView)
self.listView.setModel(self.listViewmodel)
self.listView.setModelColumn(2)
self.grid.addWidget(self.verCombo, 0, 0, 1, 3)
self.grid.addWidget(self.listView, 2, 0, 3, 3)
self.listView.clicked[QtCore.QModelIndex].connect(self.on_clicked)
self.verCombo.activated[str].connect(self.onverComboActivated)
self.verCombo.addItem("1 - NO edit CKECKBOXES")
self.verCombo.addItem("2 - WITH edit CKECKBOXES")
self.verCombo.setCurrentIndex(0)
self.addrowinlistView(
'Cookie dough', # Must be store-bought
'Hummus', # Must be homemade
'Spaghetti', # Must be saucy
'Dal makhani', # Must be spicy
'Chocolate whipped cream' # Must be plentiful
)
self.setLayout(self.grid)
chechAllSelected_resulr1, \
chechAllSelected_resulr2, \
chechAllSelected_resulr3, \
chechAllSelected_resulr4 = self.chechAllSelected()
def chechAllSelected (self):
SelectedList = []
list_of_indexes_selectedLayers = []
list_of_texts_selectedLayers = []
Items_list = []
#item = self.listView.itemFromIndex()
selectedLayers = self.listView.selectedIndexes()
if self.verCombo.currentIndex()+1 == 1:
print ("Here for check")
for i in selectedLayers:
item = self.listViewmodel.itemFromIndex(i)
Items_list.append(item)
list_of_indexes_selectedLayers.append(item.index().row())
list_of_indexes_selectedLayers.sort()
for i in range(len(list_of_indexes_selectedLayers)):
SelectedList.append(int(list_of_indexes_selectedLayers[i]))
item = self.listViewmodel.itemFromIndex(
self.listViewmodel.index(int(list_of_indexes_selectedLayers[i]), 0))
list_of_texts_selectedLayers.append(item.text())
print("List: ", list_of_indexes_selectedLayers, " ", list_of_texts_selectedLayers, " ", Items_list)
else:
for i in range(self.listViewmodel.rowCount()):
if self.listViewmodel.item(i).checkState():
SelectedList.append(i)
if len(SelectedList)==0: res_chechAllSelected = 0
if 0<len(SelectedList)<self.listViewmodel.rowCount(): res_chechAllSelected = 1
if 0<len(SelectedList) == self.listViewmodel.rowCount(): res_chechAllSelected = 2
print ("В модуле chechAllSelected:", len(SelectedList)," ", self.listViewmodel.rowCount()," ", res_chechAllSelected, " ", SelectedList)
return len(SelectedList), self.listViewmodel.rowCount(), res_chechAllSelected, SelectedList
def addrowinlistView(self, *rowsforadd):
for i in rowsforadd:
# Create an item with a caption
item = QtGui.QStandardItem(i)
# Add a checkbox to it
item.setCheckState(True) # +
Chous_for_random = [0, 2]
if self.verCombo.currentIndex() + 1 == 1:
#print("индекс переключателя: ",self.verCombo.currentIndex() + 1)
item.setCheckable(False)
self.listViewmodel.appendRow(item)
if random.choice(Chous_for_random)==2:
index = self.listViewmodel.indexFromItem(item)
sm = self.listView.selectionModel()
sm.select(index, QtCore.QItemSelectionModel.Select)
else:
item.setCheckable(True)
item.setCheckState(random.choice(Chous_for_random))
self.listViewmodel.appendRow(item)
# Add the item to the model
#self.listViewmodel.appendRow(item)
#self.BaseWidget.listViewmodel.appendRow(item)
def on_clicked(self, index):
item = self.listViewmodel.itemFromIndex(index)
print(f"\nitem={item.text()}, index={index.row()}\n" )
myitem = QtWidgets.QListWidgetItem()
#print (("on_clicked: itemIndex='{}', itemText='{}'"
# .format(item.index().row(), item.text())))
if self.verCombo.currentIndex()+1 == 1:
# print(item.index().row())
pass
else:
print("This position: ", int(item.index().row()))
chechAllSelected_resulr1, chechAllSelected_resulr2, chechAllSelected_resulr3, chechAllSelected_resulr4 = self.chechAllSelected()
self.StartList = chechAllSelected_resulr4
if self.listViewmodel.item(item.index().row()).checkState():
item.setCheckState(0)
self.StartList.remove(item.index().row())
else:
item.setCheckState(2)
self.StartList.append(item.index().row())
print("Now here")
chechAllSelected_resulr1, chechAllSelected_resulr2, chechAllSelected_resulr3, chechAllSelected_resulr4 = self.chechAllSelected()
#print("Now here")
#self.on_chechBox_click(FType=False, FClick=0, FStatus=chechAllSelected_resulr3)
#self.chechAllSelected()
#self.listViewmodel.removeRow(item.index().row())
def onverComboActivated(self, text):
self.verCombo.setCurrentText(text)
len_SelectedList, listViewmodel_rowCount, res_chechAllSelected, SelectedLis = self.chechAllSelected()
print ("\nFor print: \n\tlen_SelectedList = {}; \n\tlistViewmodel_rowCount = {};\
\n\tres_chechAllSelected = {}; \n\tSelectedLis = {}"
"".format(len_SelectedList, listViewmodel_rowCount, res_chechAllSelected, SelectedLis))
# ? self.show_hide_ckeckinlistView(
# self.verCombo.currentIndex(),
# listViewmodel_rowCount,
# SelectedLis
# )
print(self.verCombo.currentText())
# print(self.verCombo.currentText()," индекс = ", self.verCombo.currentIndex())
# self.chechAllSelected ()
""" ??????????????????????????????????????????????????
def on_clicked(self, index):
item = self.listViewmodel.itemFromIndex(index)
myitem=QtWidgets.QListWidgetItem()
#print (("on_clicked: itemIndex='{}', itemText='{}'"
# .format(item.index().row(), item.text())))
if self.verCombo.currentIndex()+1==1:
# print(item.index().row())
pass
else:
print("This position: ", int(item.index().row()))
chechAllSelected_resulr1, chechAllSelected_resulr2, chechAllSelected_resulr3, chechAllSelected_resulr4 = self.chechAllSelected()
self.StartList = chechAllSelected_resulr4
if self.listViewmodel.item(item.index().row()).checkState():
item.setCheckState(0)
self.StartList.remove(item.index().row())
else:
item.setCheckState(2)
self.StartList.append(item.index().row())
print("Now here")
#chechAllSelected_resulr1, chechAllSelected_resulr2, chechAllSelected_resulr3, chechAllSelected_resulr4 = self.chechAllSelected()
print("Now here")
#self.on_chechBox_click(FType=False, FClick=0, FStatus=chechAllSelected_resulr3)
#self.chechAllSelected()
#self.listViewmodel.removeRow(item.index().row())
"""
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
w = HelloApplication()
w.show()
sys.exit(app.exec_())
I would like to be able to select a date from a calendar in a combobox.
The answer given here Showing a gtk.Calendar in a menu? doesn't satisfy me since it seems possible to do it better using a custom cell renderer as shown there: http://faq.pygtk.org/index.py?req=show&file=faq13.056.htp
but i'm not able to use the renderer correctly.
The code below shows you what i have, but it just gives a combobox with nothing in it and no drop-down menu.
Do i have to connect a combobox signal to the do_start_editing function from the CellRendererDate class? (and then how?) or what is missing?
class MyWindow(gtk.Window):
....
liststore=gtk.ListStore(str)
cell=CellRendererDate()
cell.set_property('editable',True)
combo=gtk.ComboBox(liststore)
combo.pack_start(cell, True)
combo.add_attribute(cell, 'text', 0)
....
class CellRendererDate(gtk.CellRendererText): # code from the pygtk FAQ, linked above
__gtype_name__ = 'CellRendererDate'
def __init__(self):
gtk.CellRendererText.__init__(self)
self.date_format = '%d/%m/%Y'
self.calendar_window = None
self.calendar = None
def _create_calendar(self, treeview):
self.calendar_window = gtk.Dialog(parent=treeview.get_toplevel())
self.calendar_window.action_area.hide()
self.calendar_window.set_decorated(False)
self.calendar_window.set_property('skip-taskbar-hint', True)
self.calendar = gtk.Calendar()
self.calendar.display_options(gtk.CALENDAR_SHOW_DAY_NAMES | gtk.CALENDAR_SHOW_HEADING)
self.calendar.connect('day-selected-double-click', self._day_selected, None)
self.calendar.connect('key-press-event', self._day_selected)
self.calendar.connect('focus-out-event', self._selection_cancelled)
self.calendar_window.set_transient_for(None) # cancel the modality of dialog
self.calendar_window.vbox.pack_start(self.calendar)
# necessary for getting the (width, height) of calendar_window
self.calendar.show()
self.calendar_window.realize()
def do_start_editing(self, event, treeview, path, background_area, cell_area, flags):
if not self.get_property('editable'):
return
if not self.calendar_window:
self._create_calendar(treeview)
# select cell's previously stored date if any exists - or today
if self.get_property('text'):
date = datetime.datetime.strptime(self.get_property('text'), self.date_format)
else:
date = datetime.datetime.today()
self.calendar.freeze() # prevent flicker
(year, month, day) = (date.year, date.month - 1, date.day) # datetime's month starts from one
self.calendar.select_month(int(month), int(year))
self.calendar.select_day(int(day))
self.calendar.thaw()
# position the popup below the edited cell (and try hard to keep the popup within the toplevel window)
(tree_x, tree_y) = treeview.get_bin_window().get_origin()
(tree_w, tree_h) = treeview.window.get_geometry()[2:4]
(calendar_w, calendar_h) = self.calendar_window.window.get_geometry()[2:4]
x = tree_x + min(cell_area.x, tree_w - calendar_w + treeview.get_visible_rect().x)
y = tree_y + min(cell_area.y, tree_h - calendar_h + treeview.get_visible_rect().y)
self.calendar_window.move(x, y)
response = self.calendar_window.run()
if response == gtk.RESPONSE_OK:
(year, month, day) = self.calendar.get_date()
date = datetime.date(year, month + 1, day).strftime (self.date_format) # gtk.Calendar's month starts from zero
self.emit('edited', path, date)
self.calendar_window.hide()
return None # don't return any editable, our gtk.Dialog did the work already
def _day_selected(self, calendar, event):
# event == None for day selected via doubleclick
if not event or event.type == gtk.gdk.KEY_PRESS and gtk.gdk.keyval_name(event.keyval) == 'Return':
self.calendar_window.response(gtk.RESPONSE_OK)
return True
def _selection_cancelled(self, calendar, event):
self.calendar_window.response(gtk.RESPONSE_CANCEL)
return True
Check Kiwi's DateEntry:
http://doc.stoq.com.br/api/kiwi/_modules/kiwi/ui/dateentry.html
Ok, let's get straight to the point. I got 2 questions
1. Why self.StyleSetSpec(stc.STC_STYLE_DEFAULT, "fore:#000000" + FontSet) not working?
2. Why the custom lexer is not applied?
This is the source code
import wx, re, keyword
from wx import stc
class BaseLexer(object):
"""Defines simple interface for custom lexer objects"""
def __init__(self):
super(BaseLexer, self).__init__()
def StyleText(self, event):
raise NotImplementedError
class STC_LEX_VOTONUSA(BaseLexer):
# Define some style IDs
STC_VOTONUSA_DEFAULT = wx.NewId()
STC_VOTONUSA_VALUE = wx.NewId()
STC_VOTONUSA_OBJECT = wx.NewId()
STC_VOTONUSA_TYPE = wx.NewId()
STC_VOTONUSA_OPERATION = wx.NewId()
STC_VOTONUSA_COMMENT =wx.NewId()
STC_VOTONUSA_QUALIFIER = wx.NewId()
def __init__(self):
super(STC_LEX_VOTONUSA, self).__init__()
# Attributes
self.Comment = re.compile("""
//
""", re.X)
self.Types = re.compile("""
\\b
(void|integer|shortint|(short)?word|float|boolean|char|record|program|module)
\\b
""", re.I|re.X)
self.Operation = re.compile("""
(read|write)(line)?|if|main|case|while|use|return|exit|in_case|repeat_until
(\+|-|\*|/|%|\*\*|:|!|<|>)?=?|
(\{|\}|\(|\)|\[|\])
""", re.I|re.X)
self.Value = re.compile("""
[(`\d*)+\'\w*\']*|\'.*\'|[\+-]*\d*\.?\d*
""", re.I|re.X)
self.Qualifier = re.compile("""
interface|implementation
""", re.I|re.X)
self.Object = re.compile("""
s
""", re.I|re.X)
def GetLastWord(self, Line, CaretPos):
"""
Get the last word from a line
"""
LastWord = re.search(
"""
\s*
(
".*"| # String data type
\w*| # Any letter/number
(\+|-|\*|/|%|\*\*|:|!|<|>)?=?| # Assignment, Comparison & Mathematical
(\{|\}|\(|\)|\[|\]) # Brackets
)
\s*\Z
""",
Line[:CaretPos], re.VERBOSE)
return LastWord
def StyleText(self, event):
"""Handle the EVT_STC_STYLENEEDED event"""
Obj = event.GetEventObject()
# Get Last Correctly Styled
LastStyledPos = Obj.GetEndStyled()
# Get Styling Range
Line = Obj.LineFromPosition(LastStyledPos)
StartPos = Obj.PositionFromLine(Line)
EndPos = event.GetPosition()
# Walk the Range and Style Them
while StartPos < EndPos:
Obj.StartStyling(StartPos, 0x1f)
LastWord = self.GetLastWord(Line, CaretPos)
if self.Comment.search(LastWord):
# Set Comment Keyword style
Style = self.STC_VOTONUSA_COMMENT
elif self.Type.search(LastWord):
# Set Type Keyword style
Style = self.STC_VOTONUSA_TYPE
elif self.Operation.search(LastWord):
# Set Operation Keyword style
Style = self.STC_VOTONUSA_OPERATION
elif self.Value.search(LastWord):
# Set Value Keyword style
Style = self.STC_VOTONUSA_VALUE
elif self.Qualifier.search(LastWord):
# Set Qualifier Keyqord style
Style = self.STC_VOTONUSA_QUALIFIER
elif self.Object.search(LastWord):
# Set Object Keyword style
Style = self.STC_VOTONUSA_OBJECT
# Set the styling byte information for length of LastWord from
# current styling position (StartPos) with the given style.
Obj.SetStyling(len(LastWord), Style)
StartPos += len(LastWord)
class CustomSTC(stc.StyledTextCtrl):
def __init__(self, parent):
super(CustomSTC, self).__init__(parent)
# Attributes
self.custlex = None
Font = wx.Font(12, wx.FONTFAMILY_MODERN, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL)
Face = Font.GetFaceName()
Size = Font.GetPointSize()
# Setup
kwlist = u" ".join(keyword.kwlist)
self.SetKeyWords(0, kwlist)
self.StyleClearAll()
self.SetLexer(wx.NewId(), STC_LEX_VOTONUSA)
self.EnableLineNumbers()
FontSet = "face:%s, size:%d" % (Face, Size)
self.StyleSetSpec(stc.STC_STYLE_LINENUMBER, FontSet)
# Set Default to Black
self.StyleSetSpec(stc.STC_STYLE_DEFAULT, "fore:#000000" + FontSet)
# Set Comment to Pink
self.StyleSetSpec(STC_LEX_VOTONUSA.STC_VOTONUSA_COMMENT, "fore:#ff007f" + FontSet)
# Set Value to Green
self.StyleSetSpec(STC_LEX_VOTONUSA.STC_VOTONUSA_VALUE, "fore:#00ff00" + FontSet)
# Set Object to Brown
self.StyleSetSpec(STC_LEX_VOTONUSA.STC_VOTONUSA_OBJECT, "fore:#a52a2a" + FontSet)
# Set Type to Red
self.StyleSetSpec(STC_LEX_VOTONUSA.STC_VOTONUSA_TYPE, "fore:#ff0000" + FontSet)
# Set Operation to Blue
self.StyleSetSpec(STC_LEX_VOTONUSA.STC_VOTONUSA_OPERATION, "fore:#0000ff" + FontSet)
# Set Qualifier to Orange
self.StyleSetSpec(STC_LEX_VOTONUSA.STC_VOTONUSA_QUALIFIER, "fore:#cc3232" + FontSet)
# Event Handlers
self.Bind(stc.EVT_STC_STYLENEEDED, self.OnStyle)
def EnableLineNumbers(self, enable=True):
"""Enable/Disable line number margin"""
if enable:
self.SetMarginType(1, stc.STC_MARGIN_NUMBER)
self.SetMarginMask(1, 0)
self.SetMarginWidth(1, 25)
else:
self.SetMarginWidth(1, 0)
def OnStyle(self, event):
# Delegate to custom lexer object if one exists
if self.custlex:
self.custlex.StyleText(event)
else:
event.Skip()
def SetLexer(self, lexerid, lexer=None):
"""
Overrides StyledTextCtrl.SetLexer
Adds optional param to pass in custom container
lexer object.
"""
self.custlex = lexer
super(CustomSTC, self).SetLexer(lexerid)
class NUSAIPT(wx.Frame):
def __init__(self, *args, **kwargs):
wx.Frame.__init__(self, None, wx.ID_ANY, 'VOTO NUSA IPT')
self.TextArea = CustomSTC(self)
self.Show()
app = wx.App()
frame = NUSAIPT()
app.MainLoop()
If I change
self.SetLexer(wx.NewId(), STC_LEX_VOTONUSA)
into
self.SetLexer(stc.STC_LEX_CPP)
and
self.StyleSetSpec(STC_LEX_VOTONUSA.STC_VOTONUSA_COMMENT, "fore:#ff007f" + FontSet)
into
self.StyleSetSpec(stc.STC_C_COMMENT, "fore:#ff007f" + FontSet)
the comment highlighting worked. so the mistake should be in self.SetLexer(wx.NewId(), STC_LEX_VOTONUSA) or STC_LEX_VOTONUSA.STC_VOTONUSA_COMMENT
Thanks in advance. Hope to see some answer soon.
Just stuck with same problem yesterday, here are my results. Hope it's not too late :)
First, i set lexer to this one, and internal lexer as you do:
self.SetLexer(stc.STC_LEX_CONTAINER)
self.custlex = SCT_LEX_ERLANG_IDNOISE(self)
Bind to event and OnStyle method are same.
And also i changed id of styles from wx.newId() to just numbers starting from 1.
Without it i didn't see any styling at all. Also stc.STC_STYLE_DEFAULT started to work too.
Full listing:
class SCT_LEX_ERLANG_IDNOISE(BaseLexer):
STC_ERLANG_IDNOISE_DEFAULT = 1
STC_ERLANG_IDNOISE_VARIABLE = 2
STC_ERLANG_IDNOISE_ATOM = 3
STC_ERLANG_IDNOISE_MODULE = 4
STC_ERLANG_IDNOISE_KEYWORD = 5
STC_ERLANG_IDNOISE_COMMENT = 6
STC_ERLANG_IDNOISE_MACROS = 7
STC_ERLANG_IDNOISE_NUMBER = 8
def __init__(self, control):
super(SCT_LEX_ERLANG_IDNOISE, self).__init__(control)
self.typeFormatDict = {}
self.typeFormatDict["other"] = SCT_LEX_ERLANG_IDNOISE.STC_ERLANG_IDNOISE_DEFAULT
self.typeFormatDict["variable"] = SCT_LEX_ERLANG_IDNOISE.STC_ERLANG_IDNOISE_VARIABLE
self.typeFormatDict["atom"] = SCT_LEX_ERLANG_IDNOISE.STC_ERLANG_IDNOISE_ATOM
self.typeFormatDict["module"] = SCT_LEX_ERLANG_IDNOISE.STC_ERLANG_IDNOISE_MODULE
self.typeFormatDict["keyword"] = SCT_LEX_ERLANG_IDNOISE.STC_ERLANG_IDNOISE_KEYWORD
self.typeFormatDict["comment"] = SCT_LEX_ERLANG_IDNOISE.STC_ERLANG_IDNOISE_COMMENT
self.typeFormatDict["macros"] = SCT_LEX_ERLANG_IDNOISE.STC_ERLANG_IDNOISE_MACROS
self.typeFormatDict["number"] = SCT_LEX_ERLANG_IDNOISE.STC_ERLANG_IDNOISE_NUMBER
def StyleText(self, event):
start = self.control.GetEndStyled()
end = event.GetPosition()
line = self.control.LineFromPosition(start)
start = self.control.PositionFromLine(line)
text = self.control.GetTextRange(start, end)
self.control.StartStyling(start, 0x1f)
lastEnd = 0
for type, start, end, value in getHighlightRules(text):
style = SCT_LEX_ERLANG_IDNOISE.STC_ERLANG_IDNOISE_DEFAULT
if start > lastEnd:
self.control.SetStyling(start - lastEnd, style)
if type in self.typeFormatDict:
style = self.typeFormatDict[type]
self.control.SetStyling(len(value), style)
lastEnd = end
class CustomSTC(stc.StyledTextCtrl):
def __init__(self, parent):
super(CustomSTC, self).__init__(parent)
self.custlex = SCT_LEX_ERLANG_IDNOISE(self)
#self.SetKeyWords(0, kwlist)
self.SetLexer(stc.STC_LEX_CONTAINER)
self.EnableLineNumbers()
self.StyleSetSpec(stc.STC_STYLE_DEFAULT, ColorSchema.formats["other"])
self.StyleClearAll()
self.StyleSetSpec(stc.STC_STYLE_LINENUMBER, ColorSchema.lineFont)
self.StyleSetSpec(SCT_LEX_ERLANG_IDNOISE.STC_ERLANG_IDNOISE_DEFAULT, ColorSchema.formats["other"])
self.StyleSetSpec(SCT_LEX_ERLANG_IDNOISE.STC_ERLANG_IDNOISE_VARIABLE, ColorSchema.formats["variable"])
self.StyleSetSpec(SCT_LEX_ERLANG_IDNOISE.STC_ERLANG_IDNOISE_ATOM, ColorSchema.formats["atom"])
self.StyleSetSpec(SCT_LEX_ERLANG_IDNOISE.STC_ERLANG_IDNOISE_MODULE, ColorSchema.formats["module"])
self.StyleSetSpec(SCT_LEX_ERLANG_IDNOISE.STC_ERLANG_IDNOISE_KEYWORD, ColorSchema.formats["keyword"])
self.StyleSetSpec(SCT_LEX_ERLANG_IDNOISE.STC_ERLANG_IDNOISE_COMMENT, ColorSchema.formats["comment"])
self.StyleSetSpec(SCT_LEX_ERLANG_IDNOISE.STC_ERLANG_IDNOISE_MACROS, ColorSchema.formats["macros"])
self.StyleSetSpec(SCT_LEX_ERLANG_IDNOISE.STC_ERLANG_IDNOISE_NUMBER, ColorSchema.formats["number"])
# Event Handlers
self.Bind(stc.EVT_STC_STYLENEEDED, self.OnStyle)
def EnableLineNumbers(self, enable=True):
"""Enable/Disable line number margin"""
if enable:
self.SetMarginType(1, stc.STC_MARGIN_NUMBER)
self.SetMarginMask(1, 0)
self.SetMarginWidth(1, 35)
else:
self.SetMarginWidth(1, 0)
def OnStyle(self, event):
if self.custlex:
self.custlex.StyleText(event)
else:
event.Skip()
How would I add another event to the pane created in our GUI manager class (below). I want to detect when the x button closes the pane. I've tried using the same format as wx.EVT_MENU for wx.EVT_CLOSE but it didn't work.
def popup_panel(self, p):
"""
Add a panel object to the AUI manager
:param p: panel object to add to the AUI manager
:return: ID of the event associated with the new panel [int]
"""
ID = wx.NewId()
self.panels[str(ID)] = p
self.graph_num += 1
if p.window_caption.split()[0] in NOT_SO_GRAPH_LIST:
windowcaption = p.window_caption
else:
windowcaption = 'Graph'#p.window_caption
windowname = p.window_name
# Append nummber
captions = self._get_plotpanel_captions()
while (1):
caption = windowcaption + '%s'% str(self.graph_num)
if caption not in captions:
break
self.graph_num += 1
# protection from forever-loop: max num = 1000
if self.graph_num > 1000:
break
if p.window_caption.split()[0] not in NOT_SO_GRAPH_LIST:
p.window_caption = caption
#p.window_caption = windowcaption+ str(self.graph_num)
p.window_name = windowname + str(self.graph_num)
style1 = self.__gui_style & GUIFRAME.FIXED_PANEL
style2 = self.__gui_style & GUIFRAME.FLOATING_PANEL
if style1 == GUIFRAME.FIXED_PANEL:
self._mgr.AddPane(p, wx.aui.AuiPaneInfo().
Name(p.window_name).
Caption(p.window_caption).
Position(10).
Floatable().
Right().
Dock().
MinimizeButton().
Resizable(True).
# Use a large best size to make sure the AUI
# manager takes all the available space
BestSize(wx.Size(PLOPANEL_WIDTH,
PLOPANEL_HEIGTH)))
self._popup_fixed_panel(p)
elif style2 == GUIFRAME.FLOATING_PANEL:
self._mgr.AddPane(p, wx.aui.AuiPaneInfo().
Name(p.window_name).Caption(p.window_caption).
MinimizeButton().
Resizable(True).
# Use a large best size to make sure the AUI
# manager takes all the available space
BestSize(wx.Size(PLOPANEL_WIDTH,
PLOPANEL_HEIGTH)))
self._popup_floating_panel(p)
# Register for showing/hiding the panel
wx.EVT_MENU(self, ID, self.on_view)
if p not in self.plot_panels.values() and p.group_id != None:
self.plot_panels[ID] = p
if len(self.plot_panels) == 1:
self.panel_on_focus = p
self.set_panel_on_focus(None)
if self._data_panel is not None and \
self._plotting_plugin is not None:
ind = self._data_panel.cb_plotpanel.FindString('None')
if ind != wx.NOT_FOUND:
self._data_panel.cb_plotpanel.Delete(ind)
if caption not in self._data_panel.cb_plotpanel.GetItems():
self._data_panel.cb_plotpanel.Append(str(caption), p)
return ID
I want to be able to pick up the event in the plotting child class.
def create_panel_helper(self, new_panel, data, group_id, title=None):
"""
"""
## Set group ID if available
## Assign data properties to the new create panel
new_panel.set_manager(self)
new_panel.group_id = group_id
if group_id not in data.list_group_id:
data.list_group_id.append(group_id)
if title is None:
title = data.title
new_panel.window_caption = title
new_panel.window_name = data.title
event_id = self.parent.popup_panel(new_panel)
#remove the default item in the menu
if len(self.plot_panels) == 0:
pos = self.menu.FindItem(DEFAULT_MENU_ITEM_LABEL)
if pos != -1:
self.menu.Delete(DEFAULT_MENU_ITEM_ID)
# Set UID to allow us to reference the panel later
new_panel.uid = event_id
# Ship the plottable to its panel
wx.CallAfter(new_panel.plot_data, data)
self.plot_panels[new_panel.group_id] = new_panel
# Set Graph menu and help string
helpString = 'Show/Hide Graph: '
for plot in new_panel.plots.itervalues():
helpString += (' ' + plot.label + ';')
self.menu.AppendCheckItem(event_id, new_panel.window_caption,
helpString)
self.menu.Check(event_id, IS_WIN)
wx.EVT_MENU(self.parent, event_id, self._on_check_menu)
wx.EVT_CLOSE(self.parent, event_id, self._on_close_panel)
wx.EVT_SHOW(new_panel, self._on_show_panel)
Did you try catching wx.aui.EVT_AUINOTEBOOK_PAGE_CLOSE or wx.aui.EVT_AUINOTEBOOK_PAGE_CLOSED? I would think that would do what you want. I am assuming you're using wx.aui rather than wx.agw.aui. I suspect the latter is similar though.
EDIT: Oops. I read this wrong. I thought the OP wanted to know about AUINotebook. The event you're probably looking for is wx.aui.EVT_AUI_PANE_CLOSE