select a line and process its tags on mouse click (python tkinter) - python-2.7

Hi I’m developing a user interface for processing AI (Adobe illustrator) files, I have grouped sets of lines, using the tag feature. I want to know which set of lines is selected on click (which tag for example), but I can't figure out how, as the function click_poligono always gets the last tag, any help on how I'm supposed to do this??
part of my code is :
def click_poligono(self,event,poligono):
self.canvas.itemconfigure('poligono%s'%poligono , fill = 'blue')
def cambio_listbox(self,*args,**kwargs):
<-------Mysql queries and processes------->
for i in range(len(matriz_start)):
print i
self.canvas.tag_bind('poligono%s'%i , '<ButtonPress-1>' , lambda event: self.click_poligono(event,'%s' % i)
for j in range(len(matriz_start[i])):
if True: #if for possible matrix condition
self.canvas.create_line(10+matriz_start[i][j]['x']*680/maximo,690-(matriz_start[i][j]['y']*680/maximo),10+matriz_end[i][j]['x']*680/maximo,690-(matriz_end[i][j]['y']*680/maximo), width = 2 ,tags ='poligono%s'%i)
So the question here is , how can I manage to select the set of lines I click with the mouse , and process it on one function , as the set of lines is variable depending on the number of figures the file (Adobe Illustrator) has..
I hope I'm clear on what I'm asking, and I'm open to new suggestions on my code.

I guess it's because of lambda.
You have
lambda event: self.click_poligono(event,'%s' % i)
where event is local variable but i is not.
Try this
lambda event, i=i: self.click_poligono(event,'%s' % i)

Related

AWS Textract (OCR) not detecting some cells

I am using AWS Textract to read and parse tables from PDF into CSV. Lovely, AWS has a documentation for it! https://docs.aws.amazon.com/textract/latest/dg/examples-export-table-csv.html
I have set up the Asynchronous method as they suggest, and it works for a POC. However, for some documents, some lines are not shown in my csv.
After digging a bit into the json produced (the issue is persistent if I use AWS CLI to make the document analysis), I noticed that the values missing have no CELL block referenced. Those missing values are referenced into WORD block, and LINE block, but not in CELL block. According to the script, that's exactly the reason why it's not added to my csv.
We could assume it's not that good OCR algorithm. But the fun fact about this, is that if I use the same pdf within AWS Textract console, all the data is parsed into the table!
Is any of you aware of any parameters I would need to use to be sure to detect the values as CELL? Or do you think behind the scenes, they simply use a more powerful script (that would actually use the (x,y) coordinates of each WORD to match the table?
I also compared the json produced from CLI to the one from the console, and it's actually different! (not only IDs, but also as said some values are in CELL's block for console, while in LINE/WORD only for CLI)
Important fact: my PDF is 3 pages long. The first page is working perfectly fine with all the values, but the second one is missing the first 10 lines of the table basically. After those 10 lines, everything is parsed on this page as well.
Any suggestions? Or script to parse more efficiently the json provided?
Thank you!
Update: Basically the issue was the pagination of the results. There is a maximum of 1000 objects according to AWS documentation: https://docs.aws.amazon.com/textract/latest/dg/API_GetDocumentAnalysis.html#API_GetDocumentAnalysis_RequestSyntax
If you have more than this amount of object in the single table, then the IDs are in the first 1000, while the object itself is referenced in second batch (1001 --> 2000). So when trying to add the cell to the table, it can't find the reference.
Basically the solution is quite easy. We need to alter the GetResults function to concatenate each response, and THEN run the other functions.
Here is a functioning code:
def GetResults(jobId, file_name):
maxResults = 1000
paginationToken = None
finished = False
blocks = []
while finished == False:
response = None
if paginationToken == None:
response = textract.get_document_analysis(JobId=jobId, MaxResults=maxResults)
else:
response = textract.get_document_analysis(JobId=jobId, MaxResults=maxResults,
NextToken=paginationToken)
blocks += response['Blocks']
if 'NextToken' in response:
paginationToken = response['NextToken']
else:
finished = True
table_csv = get_table_csv_results(blocks)
output_file = file_name + ".csv"
# replace content
with open(output_file, "w") as fout: # Important to change "at" to "w"
fout.write(table_csv)
# show the results
print('Detected Document Text')
print('Pages: {}'.format(response['DocumentMetadata']['Pages']))
print('OUTPUT TO CSV FILE: ', output_file)
Hope this will help people.

This cell duplicates image in that cell in spreadsheet?

Very simple. Cell A1 has an image in it, which I supply through Insert:Picture:From File...
Now I want Cell A3 to automatically show the same picture. I simply can't find a way-- certainly the "=" doesn't work. At this point, I don't care if the images are "links" or embedded, I just want it to work. Can it? Thx.
Edit, 09-01-17, based on Jim K's idea, here's macro code I have installed:
REM ***** BASIC *****
Private oListener as Object
Private cellA1 as Object
Sub AddListener
Dim Doc, Sheet, Cell as Object
Doc = ThisComponent
Sheet = Doc.Sheets.getByName("Sheet1")
cellA1 = Sheet.getCellrangeByName("A1")
'create a listener
oListener = createUnoListener("Modify_","com.sun.star.util.XModifyListener")
'register the listener
cellA1.addModifyListener(oListener)
End Sub
Sub Modify_disposing(oEv)
End Sub
Sub RmvListener
cellA1.removeModifyListener(oListener)
End Sub
' macro jumps here when oListener detects modification of Sheet
Sub Modify_modified(oEv)
Doc = ThisComponent
Sheet = Doc.Sheets.getByIndex(0)
originCell = Sheet.getCellByPosition(0,0)
originValue = originCell.Value
if originValue then
print "originValue is " & originValue
else
print "originValue zero"
end if
End Sub
The problem, ironically, is that it works. It works for integers and {non-value}, I mean an empty cell.
So any integer not zero prints TRUE, zero prints FALSE, and empty cell prints FALSE.
But that's where it quits working-- any kind of string "asdf" also returns FALSE.
Maybe that could be fixed, but there's something a lot worse: When I paste an image in the cell, or use the Insert/Image/From File... menu, or Cut an existing image... Nothing happens! The Sheet Modified business does not trigger the expected routine.
Any hope? Thx.
As you discovered, the solution in my comment does not work, because the Content changed event will not trigger when images are added. I looked into other events as well, but they did not work either.
So instead, we can set up a function that runs periodically. Each time it runs, it checks the count of images, and if any have been added or removed, it calls update_copied_images() below, which currently simply reports the value of cell A1, as in your code.
As explained here, I have not gotten a timer loop to work in Basic without crashing, so we can use Python instead (a better language, so this is not a drawback in my opinion).
import time
from threading import Thread
import uno
COLUMN_A, COLUMN_B, COLUMN_C = 0, 1, 2
FIRST_ROW = 0
def start_counting_images(action_event=None):
t = Thread(target = keep_counting_images)
t.start()
def keep_counting_images():
oDoc = XSCRIPTCONTEXT.getDocument()
oSheet = oDoc.getSheets().getByIndex(0)
oDrawPage = oSheet.getDrawPage()
messageCell = oSheet.getCellByPosition(COLUMN_C, FIRST_ROW)
messageCell.setString("Starting...")
prevCount = -1
while hasattr(oDoc, 'calculateAll'): # keep going until document is closed
count = oDrawPage.Count
if prevCount == -1 or prevCount != count:
prevCount = count
messageCell.setString("Number of Images: " + str(prevCount))
update_copied_images(oSheet)
time.sleep(1)
def update_copied_images(oSheet):
originCell = oSheet.getCellByPosition(COLUMN_A, FIRST_ROW)
originString = originCell.getString()
messageCell = oSheet.getCellByPosition(COLUMN_B, FIRST_ROW)
if len(originString):
messageCell.setString("originString '" + originString + "'")
else:
messageCell.setString("originString length is zero")
g_exportedScripts = start_counting_images,
To run, go to Tools -> Macros -> Run Macro, find the .py file under My Macros where you put this code, and run start_counting_images.

Autohotkey if statement not working, no error msg

I'm trying to use autohotkey to gather a chuck of data from a website and then click a certain spot on the website depending on what the text is. I'm able to get it to actually pick up the value but when it comes to the if statement it won't seem to process and yields no error message. Here is a quick sample of my code, there is about 20 if statement values so for brevity sake I've only included a few of the values.
GuessesLeft = 20
Errorcount = 0
;triple click and copy text making a variable out of the clipboard
;while (GuessesLeft!=0) part of future while loop
;{ part of future while loop
click 927,349
click 927,349
click 927,349
Send ^c
GetValue = %Clipboard%
if ( GetValue = "Frontal boss")
{
click 955,485
Guessesleft -= 1
}
else if ( GetValue = "Supraorbital Ridge")
{
click 955,571
Guessesleft -= 1
}
;....ETC
else
{
Errorcount += 1
}
;} part of future while loop
Any tips on what I might be doing wrong. Ideally I'd use a case statement but AHK doesn't seem to have them.
Wait a second -- you are triple clicking to highlight a full paragraph and copying that to the clipboard and checking to see if the entirety of the copied portion is the words in the if statement, right? And your words in the copied portion have quotes around them? Probably you will have to trim off any trailing spaces and/or returns:
GetValue = % Trim(Clipboard)
If that doesn't work, you may even have to shorten the length of the copied text by an arbitrary character or two:
GetValue = % SubStr(Clipboard, 1, (StrLen(Clipboard)-2))
Now, if I am wrong, and what you are really looking for is the words from the if statement wherever they may be in a longer paragraph -- and they are not surrounded by quotes, then you will want something like:
IfInString, Clipboard, Frontal boss
Or, if the quotes ARE there,
IfInString, Clipboard, "Frontal boss"
Hth,

Checkbuttons using dictionary will not update values

Folks,
So I've been working on a little GUI using Tkinter for a capstone project, and given the circumstances, I've only been programming for about two weeks before I was thrown into this, so I'm still a newbie.
My issue today is that I cannot manage to get my checkbutton dictionary to update values; the output for my checkbutton is always 0 or False. The code is as follows:
...
datatype= {'Joint Angle' : 0,
'Joint Acceleration' : 0,
'Ground Reaction Force' : 0,
'Muscle Activation' : 0
}
for measure in datatype:
datatype[measure] = IntVar()
dt_cb = Checkbutton(root, text=measure,
variable=datatype[measure],command = enable_location_state)
dt_cb.grid(column=0, sticky='W', padx=20)
dt1 = datatype['Joint Angle'].get()
dt2 = datatype['Joint Acceleration'].get()
dt3 = datatype['Ground Reaction Force'].get()
dt4 = datatype['Muscle Activation'].get()
...
So I tried periodically printing values throughout the code and I continued to get 0 as soon as I booted the GUI, and after that, no matter what I clicked, the numbers did not update. I read that I should try BooleanVar() and StringVar() instead, but neither of those worked. The code is based off of another bit of code I found somewhere on stackoverflow, though I cannot remember exactly where.
I tried making it a list rather than a dictionary in order to overcome my problem because I was successful with lists previously, but the list created only a single checkbutton for all of those and I was unable to differentiate what is what.
The command enable_location_state configures other checkbuttons, and is as follows:
def enable_location_state():
if dt1 == 1 or dt2 == 1:
ja_cb.configure(state=ACTIVE)
if dt3 == 1:
grf_cb.configure(state=ACTIVE)
if dt4 == 1:
emg_cb.configure(state=ACTIVE)
Your problem is that you are getting the values of the IntVar only once: at the same moment you create your buttons. Move your .get() statements to the beginning of the enable_location_state() function. That way, every time your checkbutton is clicked, the function will check on (i.e., .get()) the value of the IntVar.

Sencha Touch 2 list background change

I have a list within my application, but was wondering if it is possible to have each list displayed show a different background colour, rather than the same one through out each item?
I have created a template but would be nice to have the background of each change colour.
Thanks
EDIT: I have also created the same list via a 'Ext.dataview.component.DataItem' / 'DataView' so if this is easier to control separately then great, as I am looking at interfering in te process of creating each and setting its background, if that is at all possible.
You could try to do that with simply XTemplate:
var tpl = new Ext.XTemplate(
'<p>Name: {name}</p>',
'<p>Company: {[values.company.toUpperCase() + ", " + values.title]}</p>',
'<p>Kids: ',
'<tpl for="kids">',
'<div class="{[xindex % 2 === 0 ? "even" : "odd"]}">',
'{name}',
'</div>',
'</tpl></p>'
);
take a look at their explanations, might find something interesting:
http://docs.sencha.com/touch/2-0/#!/api/Ext.XTemplate
I have seen many variants on the Ext.query('class').up().addCls('backgroundClass'); hack, which makes perfect sense to me, but my question is WHEN are people calling this? I can't put it in 'painted', since DOM doesn't seem to exist yet.. where/when are you guys executing the Ext.get(..) call?
I have been looking for this also, and I had a hard time finding out how to access the individual items of a xlist...
This is the way I finally did it:
in your itemTpl, add a class to your < div >, using the property 'id' of your model:
itemTpl:'< div class="my_list_item_{id}"> ... content ... < /div>'
the tricky part is that if you want to set the background color of the whole item area, you have to access to < div > with class 'x-item-label' that is wrapping your itemTpl < div >.
Here is how I did it (for the first item as an example):
Ext.select('.my_list_item_1').first().up('div.x-list-item-label').addCls('background_item');
where 'background_item' is a CSS style, defining your background color.
(Since there is no way (at least that I know of) to get the index count of your items in the 'itemTpl' config, I had to use to automatic 'id' property of my model/store.
Note that if you apply filtering/sorting/... on your store, this property will not be sorted anymore. So if you want to link the order displayed in your list to the 'id' property, you have to do something like 'Ext.StoreManager.get('MyStore').getAt(indexInList).get('id') )
Hope this helps...
Since Sencha Touch 2.2.1 it's also possible to use striped parameter (more info here). It will add x-list-item-odd class to odd items of your list.