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()
Related
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 am trying to add UserControl to a WinForm using PythonNet but not having any luck. For testing, I added a button and that shows up but not the UserControl and I am not sure what I a doing wrong.
All the code can be placed into one py file. I broke into a few sections hoping it will be easier to read.
USER CONTROL
class Field(WinForms.UserControl):
def __init__(self):
self.InitializeComponents()
pass
def InitializeComponents(self):
self.components = System.ComponentModel.Container()
self.label = WinForms.Label()
self.textBox = WinForms.Label()
## Label
# self.label.Anchor = ((WinForms.AnchorStyles)(
# ((WinForms.AnchorStyles.Top | WinForms.AnchorStyles.Bottom)
# | WinForms.AnchorStyles.Left)))
self.label.AutoSize = True
self.label.Location = System.Drawing.Point(3, 7)
self.label.Name = "label"
self.label.Size = System.Drawing.Size(29, 13)
self.label.TabIndex = 0
self.label.Text = "label"
## TextBox
# self.textBox.Anchor = ((WinForms.AnchorStyles)(
# (((WinForms.AnchorStyles.Top | WinForms.AnchorStyles.Bottom)
# | WinForms.AnchorStyles.Left)
# | WinForms.AnchorStyles.Right)))
# self.textBox.Location = System.Drawing.Point(115, 3)
self.textBox.Name = "textBox"
self.textBox.Size = System.Drawing.Size(260, 20)
self.textBox.TabIndex = 1
## Control
self.AutoScaleMode = WinForms.AutoScaleMode.Font
self.Controls.Add(self.textBox)
self.Controls.Add(self.label)
self.Name = "Field"
self.Size = System.Drawing.Size(378, 26)
# self.PerformLayout()
PARENT FORM
class ParentForm(WinForms.Form):
def __init__(self):
self.InitializeComponents()
# region Form Design
def InitializeComponents(self):
self.components = System.ComponentModel.Container()
self.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
self.ClientSize = System.Drawing.Size(385, 180)
self.Name = "ParentForm"
self.Text = "Parent Form"
self.field1 = Field()
self.field1.Location = Point(13, 13)
self.field1.Name = "field1"
self.field1.Size = Size(378, 26)
self.field1.TabIndex = 1
self.Controls.Add(self.field1)
self.button1 = WinForms.Button()
self.button1.Location = Point(13, 50)
self.button1.Size = Size(50, 20)
self.button1.Text = "Button1"
self.Controls.Add(self.button1)
pass
def Dispose(self):
self.components.Dispose()
WinForms.Form.Dispose(self)
ENTRY POINT AND IMPORTS
import clr
import System
import System.Windows.Forms as WinForms
from System.IO import File
from System.Text import Encoding
from System.Drawing import Color, Point, Size
from System.Threading import ApartmentState, Thread, ThreadStart
def appThread():
app = ParentForm()
WinForms.Application.Run(app)
app.Dispose()
def appEntry():
thread = Thread(ThreadStart(appThread))
thread.SetApartmentState(ApartmentState.STA)
thread.Start()
thread.Join()
if __name__ == '__main__':
appEntry()
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()
I'm trying to create a custom ComboBox that behaves like the one in here: http://chir.ag/projects/name-that-color/
I've got two problems right now:
I can't seem to find a way to have a scrollbar on the side; the gtk.rc_parse_string function should do that, since the ComboBox widget has a "appears-as-list" style property, but my custom widget seems unaffected for some reason.
When you select a color from my widget, then click the ComboBox again, instead of showing the selected item and its neighbours, the scrolled window starts from the top, for no apparent reason.
This is the code, you can pretty much ignore the __load_name_palette method. You need the /usr/share/X11/rgb.txt file to run this code, it looks like this: http://pastebin.com/raw.php?i=dkemmEdr
import gtk
import gobject
from os.path import exists
def window_delete_event(*args):
return False
def window_destroy(*args):
gtk.main_quit()
class ColorName(gtk.ComboBox):
colors = []
def __init__(self, name_palette_path, wrap_width=1):
gtk.ComboBox.__init__(self)
liststore = gtk.ListStore(gobject.TYPE_STRING, gobject.TYPE_STRING,
gobject.TYPE_STRING)
name_palette = self.__load_name_palette(name_palette_path)
for c in name_palette:
r, g, b, name = c
if ((r + g + b) / 3.) < 128.:
fg = '#DDDDDD'
else:
fg = '#222222'
bg = "#%02X%02X%02X" % (r, g, b)
liststore.append((name, bg, fg))
self.set_model(liststore)
label = gtk.CellRendererText()
self.pack_start(label, True)
self.set_attributes(label, background=1, foreground=2, text=0)
self.set_wrap_width(wrap_width)
if len(name_palette) > 0:
self.set_active(0)
self.show_all()
def __load_name_palette(self, name_palette_path):
if exists(name_palette_path):
try:
f = open(name_palette_path,'r')
self.colors = []
palette = set()
for l in f:
foo = l.rstrip().split(None,3)
try:
rgb = [int(x) for x in foo[:3]]
name, = foo[3:]
except:
continue
k = ':'.join(foo[:3])
if k not in palette:
palette.add(k)
self.colors.append(rgb + [name])
f.close()
return self.colors
except IOError as (errno, strerror):
print "error: failed to open {0}: {1}".format(name_palette_path, strerror)
return []
else:
return []
if __name__ == '__main__':
win = gtk.Window()
#colname = ColorName('./ntc.txt')
colname = ColorName('/usr/share/X11/rgb.txt')
gtk.rc_parse_string("""style "mystyle" { GtkComboBox::appears-as-list = 1 }
class "GtkComboBox" style "mystyle" """)
print 'appears-as-list:', colname.style_get_property('appears-as-list')
model = gtk.ListStore(gobject.TYPE_STRING)
hbox = gtk.HBox()
win.add(hbox)
hbox.pack_start(colname)
win.connect('delete-event', window_delete_event)
win.connect('destroy', window_destroy)
win.show_all()
gtk.main()
The problem was the self.show_all() line. Also, you can't have a list AND a wrap_width != 1
The following PyGTk code, gives a combo-box without an active item.
This serves a case where we do not want to have a default,
and force the user to select.
Still, is there a way to have the empty combo-bar show something like:
"Select an item..."
without adding a dummy item?
import gtk
import sys
say = sys.stdout.write
def cb_changed(w):
say("Active index=%d\n" % w.get_active())
topwin = gtk.Window()
topwin.set_title("No Default")
topwin.set_size_request(0x100, 0x20)
topwin.connect('delete-event', gtk.main_quit)
vbox = gtk.VBox()
ls = gtk.ListStore(str, str)
combo = gtk.ComboBox(ls)
cell = gtk.CellRendererText()
combo.pack_start(cell)
combo.add_attribute(cell, 'text', 0)
combo.connect('changed', cb_changed)
ls.clear()
map(lambda i: ls.append(["Item-%d" % i, "Id%d" % i]), range(3))
vbox.pack_start(combo, padding=2)
topwin.add(vbox)
topwin.show_all()
gtk.main()
say("%s Exiting\n" % sys.argv[0])
sys.exit(0)
Huge hack ahead (I just added this to your program):
import gtk
import sys
say = sys.stdout.write
def cb_changed(w):
say("Active index=%d\n" % w.get_active())
topwin = gtk.Window()
topwin.set_title("No Default")
topwin.set_size_request(0x100, 0x20)
topwin.connect('delete-event', gtk.main_quit)
vbox = gtk.VBox()
ls = gtk.ListStore(str, str)
combo = gtk.ComboBox(ls)
cell = gtk.CellRendererText()
combo.pack_start(cell)
combo.add_attribute(cell, 'text', 0)
combo.connect('changed', cb_changed)
#- Begin of the hack ----------------------------------
def special_empty_text (cell_view, event):
if cell_view.window is None:
return False
row = cell_view.get_displayed_row ()
if row is not None:
return False
layout = cell_view.create_pango_layout ('bla bla bla')
context = cell_view.window.cairo_create ()
xpad = 0
ypad = 0
renderer = cell_view.get_cells () [0]
if renderer is not None:
xpad = renderer.props.xpad
ypad = renderer.props.ypad
context.move_to (cell_view.allocation.x + xpad, cell_view.allocation.y + ypad)
context.set_source_rgb (0.6, 0.6, 0.6)
context.show_layout (layout)
return True
combo.child.connect ('expose-event', special_empty_text)
#- End of the hack ----------------------------------
ls.clear()
map(lambda i: ls.append(["Item-%d" % i, "Id%d" % i]), range(3))
vbox.pack_start(combo, padding=2)
topwin.add(vbox)
topwin.show_all()
gtk.main()
say("%s Exiting\n" % sys.argv[0])
sys.exit(0)
Don't see a nicer way.