pygtk cellrenderertoggle is not checked - python

I have the following code:
self.db='checks.db'
self.con = lite.connect(self.db)
self.cur = self.con.cursor()
self.q_oblig_initial='SELECT data_plirotees.rowid as rowid,recdate,bank,amount,dueto,gto,plirstatus FROM data_plirotees WHERE plirstatus=0 ORDER BY dueto ASC'
self.store_oblig = gtk.ListStore(int,str,str,str,str,str,bool)
self.cur.execute(q_oblig)
self.data_oblig=self.cur.fetchall()
for value in self.data_oblig:
if value[6]==0:
plir=False
elif value[6]==1:
plir=True
self.store_oblig.append([value[0],datetime.datetime.fromtimestamp(int(value[1])).strftime('%d/%m/%Y'),value[2],"%.2f" %(value[3]),datetime.datetime.fromtimestamp(int(value[4])).strftime('%d/%m/%Y'),value[5],plir])`
which gets data from a sqlite database and puts it in a liststore and,
rendererToggle.connect("toggled", self.on_cell_toggled)
column_toggle = gtk.TreeViewColumn("Καλύφθηκε", rendererToggle, active=1)
column_toggle.set_fixed_width(10)
treeView_oblig.append_column(column_toggle)
which has to show it in a column where true should show a checked toggle/checkbox and false should show un-checked.
Unfortunately this doesn't happen.
The checkbox needs not to be active (i don't want it to be able to toggle) but by clicking on the treeview row it opens a new window (where a checkbutton is checked or not accordingly). From that I understand that the true/false value is contained there somewhere but it is not presented visually.
Can someone show me where I'm wrong?
I didn't post the whole program 'cause it would be too big and perhaps misguiding...

self.store_oblig = gtk.ListStore(int,str,str,str,str,str,bool)
This line creates a GtkListStore where each column is of a different type. The columns are numbered from left to right, starting at 0:
self.store_oblig = gtk.ListStore(int,str,str,str,str,str,bool)
column number 0 1 2 3 4 5 6
You create your GtkTreeViewColumn with this:
column_toggle = gtk.TreeViewColumn("Καλύφθηκε", rendererToggle, active=1)
This says that the column's cell renderer should get the value of its active property from column 1 of the model (in this case, the list store). And the active property expects a bool.
But if you look back above, column 1 isn't a bool, but rather a string! So what you really wanted was active=6, not active=1. (Your code to add to the list store, on the other hand, seems correct.)
This is what the warning Warning: unable to set property 'active' of type 'gboolean' from value of type 'gchararray' gtk.main() is trying to tell you; gchararray is (one of) GLib's internal name(s) for a string.

Related

Using copy.deepcopy with python-pptx to add a column to a table leads to cell attributes being corrupted

I'm trying to append a column to a table in PowerPoint using python-pptx. A number of threads mention the solution:
def append_col(prs_obj, sl_i, sh_i):
# prs_obj is a pptx.Presentation('path') object.
# sli_i and sh_i are int indexs to locate a particular table object.
tab = prs_obj.slides[sl_i].shapes[sh_i].table
new_col = copy.deepcopy(tab._tbl.tblGrid.gridCol_lst[-1])
tab._tbl.tblGrid.append(new_col) # copies last grid element
for tr in tab._tbl.tr_lst:
# duplicate last cell of each row
new_tc = copy.deepcopy(tr.tc_lst[-1])
tr.append(new_tc)
cell = _Cell(new_tc, tr.tc_lst)
cell.text = '--'
return tab
After running this, when you open PowerPoint the new column will be there, but it won't contain the cell.text. If you click in the cell and type, the letters will appear in the cell of the previous column. Saving powerpoint enables you to edit the column as normal, but obviously you've lost the cell.text (and formatting).
QUESTION UPDATE 1- FOLLOWING COMMENT FROM #scanny
For the simplest possible case, a (1x3) table, like so: |xx|--|xx| the tab._tbl.xml prints before and after appending the column are:
xml diff 1
xml diff 2
xml diff 3
xml diff 4
QUESTION UPDATE 2- FOLLOWING COMMENT FROM #scanny
I modified the above append_col function to forcibly remove the extLst element from the copied gridCol. This stopped the problem of typing in one cell and text appearing in another cell.
def append_col(prs_obj, sl_i, sh_i):
# existing lines removed for brevity
# New Code
tblchildren = tab._tbl.getchildren()
for child in tblchildren:
if isinstance(child, oxml.table.CT_TableGrid):
ws = set()
for j in child:
if j.w not in ws:
ws.add(j.w)
else:
for elem in j:
j.remove(elem)
return tab
However cell.text(and formatting)are still missing. Moreover, manually saving the presentation changes the tab.xml object back. The screenshots before and after manually opening the PowerPoint presentation are:
AFTER removing extLst, before manual save - xml diff 1
AFTER removing extLst, AFTER manual save - xml diff 2
If you're serious about solving this sort of problem, you'll need to reverse-engineer the Word XML for this aspect of tables.
The place to start is with before and after (adding a column) XML dumps of the table, identifying the changes made by Word, then duplicating those that matter (things like revision-numbers probably don't matter).
This process is simplified by having a small example, say a 2 x 2 table to a 2 x 3 table.
You can get the XML for a python-docx XML element using its .xml attribute, like:
print(tab._tbl.xml)
You could compare the deepcopy results and then have concrete differences to start to explain the results not working. I expect you'll find that table items have unique ids and when you duplicate those, funky things happen.
With help from Scanny, I've come up with the following workaround which works:
def append_col(prs_obj, sl_i, sh_i):
tab = prs_obj.slides[sl_i].shapes[sh_i].table
new_col = copy.deepcopy(tab._tbl.tblGrid.gridCol_lst[-1])
tab._tbl.tblGrid.append(new_col) # copies last grid element
for tr in tab._tbl.tr_lst:
new_tc = copy.deepcopy(tr.tc_lst[-1])
tr.tc_lst[-1].addnext(new_tc)
cell = _Cell(new_tc, tr.tc_lst)
for paragraph in cell.text_frame.paragraphs:
for run in paragraph.runs:
run.text = '--'
tblchildren = tab._tbl.getchildren()
for child in tblchildren:
if isinstance(child, oxml.table.CT_TableGrid):
ws = set()
for j in child:
if j.w not in ws:
ws.add(j.w)
else:
# print('j:\n', j.xml)
for elem in j:
j.remove(elem)
return tab

Using a cell value in an IF statment

I'm working on looking up a cell value, and if that cell has nothing entered I want my code to do nothing, else I want to place a label on a Tkinter canvas, for some reason no matter what I do the label always ends up showing up, should the below code work?
##Grabbing the cell value from that indexed row and specific column, in this case pulling the value of indexed cell and column "Zixi Device"
Searched_Service_Row_Location_B = (excel_data_df.iloc[Searched_Service_Row_Location]["Zixi Device"])
Searched_Service_Row_Location_B_Value = (Searched_Service_Row_Location_B.values)
I am then taking the var Searched_Service_Row_Location_B_Value in an IF statment
if Searched_Service_Row_Location_B_Value == None:
pass
else:
Source1 = Label(Standard_window, text=Searched_Service_Row_Location_B_Value)
Source1.place(x=60, y=100)
The Source1 label always shows up, even though the cell value stored in the var has nothing entered in the excel document.
This seems to work the way I want it to
if str(Searched_Service_Row_Location_B_Value) in (None, "[nan]"):
pass
else:
Source1 = Label(Standard_window, text=Searched_Service_Row_Location_B_Value)
Source1.place(x=60, y=100)

pyQt QTableView select a noncontiguous set of rows

I have a QTableView, which is created this way:
self.preset_delegate = PresetDelegate() # used to provide a combobox for making a selection from a set of options, column 0
self.model_filelist = QtGui.QStandardItemModel()
self.model_filelist.setHorizontalHeaderLabels(HEADER_LABELS)
self.list_filelist = QtGui.QTableView()
self.list_filelist.horizontalHeader().setResizeMode( QtGui.QHeaderView.Interactive )
self.list_filelist.setItemDelegateForColumn(0, self.preset_delegate )
self.list_filelist.setModel( self.model_filelist )
self.list_filelist.setSelectionMode( QtGui.QAbstractItemView.ExtendedSelection )
When the user presses a button, I would like to algorithmically select rows from the table. The selection will not be contiguous. For the purpose of our discussion, it could be any random subset of rows in the model/table.
This is pseudo-code for what I'm using to make the selection:
files = [str(self.model_filelist.data( self.model_filelist.index(x,1)).toString()) for x in range(self.model_filelist.rowCount())]
self.list_filelist.clearSelection()
for x in match_set:
match_index = files.index( x )
model_index = self.model_filelist.index(match_index,1) # first column is okay
self.list_filelist.selectionModel().select( model_index, QtGui.QItemSelectionModel.Select | QtGui.QItemSelectionModel.Current )
My problem is the with selection model flag on the very last line. Whether I use SelectCurrent, ToggleCurrent or Select | Current, or Toggle | Current, I only get the last item in my match_set remaining selected at the end of the loop. As the loop executes, the selection is changed from one item to the other, rather than adding the new row to the set of the selection. I hope that makes sense.
I thought for sure that SelectCurrent flag was the way to do this, but it's not working for me. Any suggestions? (python 2.6.7, Fedora 14, Qt4.4??? I can't be sure)
As per comments to the question. I did not solve why the original code failed, but I found this to work:
Use the version of select() that takes a QItemSelection object, and load that object with QItemSelectRange objects that wrap ModelIndex to the rows I'm interested in.

Vlookup XLRD Python

I have a xls spreadsheet that looks like below
Number Code Unit
1 Widget 1 20.0000
2 Widget 2 4.6000
3 Widget 3 2.6000
4 Widget 4 1.4500
I have created the following code:
import xlrd
wb=xlrd.open_workbook('pytest.xls')
xlsname = 'pytest.xls'
book = xlrd.open_workbook(xlsname)
sd={}
for s in book.sheets():
sd[s.name] = s
sheet=sd["Prod"]
Number = sh.col_values(0)
Code = sh.col_values(1)
Unit = sh.col_values(2)
Now this is where I am getting stuck, what i need to do is ask a question on what Number they choose, for this example lets say they choose 3, it needs to do print the answer for the unit. So if they choose 4 it prints 1.450. This document is 10k's long so manually entering the data into python is not viable.
In this case you'd just need to do this:
Unit[Number.index(value)]
Which will return the value from the Unit column that corresponds to the value specified for the Number column.
The index() function on a Python sequence returns the index of the first occurence of the provided value in the sequence. This value gets used to as the index to find the corresponding entry from Unit.

Using python win32com can't make two separate tables in MS Word 2007

I am trying to create multiple tables in a new Microsoft Word document using Python. I can create the first table okay. But I think I have the COM Range object configured wrong. It is not pointing to the end. The first table is put before "Hello I am a text!", the second table is put inside the first table's first cell. I thought that returning a Range from wordapp will return the full range, then collapse it using wdCollapseStart Enum which I think is 1. (I can't find the constants in Python win32com.). So adding a table to the end of the Range will add it to the end of the document but that is not happening.
Any ideas?
Thanks Tim
import win32com.client
wordapp = win32com.client.Dispatch("Word.Application")
wordapp.Visible = 1
worddoc = wordapp.Documents.Add()
worddoc.PageSetup.Orientation = 1
worddoc.PageSetup.BookFoldPrinting = 1
worddoc.Content.Font.Size = 11
worddoc.Content.Paragraphs.TabStops.Add (100)
worddoc.Content.Text = "Hello, I am a text!"
location = worddoc.Range()
location.Collapse(1)
location.Paragraphs.Add()
location.Collapse(1)
table = location.Tables.Add (location, 3, 4)
table.ApplyStyleHeadingRows = 1
table.AutoFormat(16)
table.Cell(1,1).Range.InsertAfter("Teacher")
location1 = worddoc.Range()
location1.Paragraphs.Add()
location1.Collapse(1)
table = location1.Tables.Add (location1, 3, 4)
table.ApplyStyleHeadingRows = 1
table.AutoFormat(16)
table.Cell(1,1).Range.InsertAfter("Teacher1")
worddoc.Content.MoveEnd
worddoc.Close() # Close the Word Document (a save-Dialog pops up)
wordapp.Quit() # Close the Word Application
The problem seems to be in the Range object that represents a part of the document. In my original code the Range object contains the first cell and starts at the first cell, where it will insert. Instead I want to insert at the end of the range. So I got the following code replacement to work. I moved the Collapse after the Add() call and gave it an argument of 0. Now there is only one Collapse call per Range object.
location = worddoc.Range()
location.Paragraphs.Add()
location.Collapse(0)
Now the code works, I can read from a database and populate new tables from each entry.
Tim

Categories

Resources