How do I get the number of the column that is selected in a tkinter treeview?
Right now I'm using tree.focus() but it returns something like I001 or I00A and I have no idea how to convert that to a number.
I can't index the tree because there are multiple items with the same name in it, and I want to know the exact column the user clicks on.
What I expect is to click the first item and get the integer 0 back, etc.
Thanks, please ask questions if I was confusing...
Here are docs for Treeview.
You have used the term "column" repeatedly, but when you say "multiple items with the same name" and refer to "first item" it sounds a lot like you're talking about rows.
If you want the column, you'll need to capture the click event using treeview.bind("<Button-1>", callback) or a variant of that. You would then use treeview.identify_column to get the column index based on the event's x location (keep in mind, per the docs, that if your columns are rearranged you may need to do some extra work). Here are two links if you need information on events.
If you were actually talking about rows, you can use treeview.selection() to get a list of iids of selected items, and then feed them into treeview.index() to get the 0-index of the row that you were talking about.
Related
I have the following problem, which doesn't seem particularly difficult, but I've been standing still for 1 day and can't find the right logic.
I have a list that searches for objects that end with the name "_ctrl". This list currently contains 4 items, but can contain any number of items. Depending on how many objects exist, it will add that many rows of buttons to the table.
My question is - how to get the index of the selected button to be printed in another function.
enter image description here
I hope you can understand me what I wanted to ask.
def refresh_table(self):
self.table_wdg.setRowCount(0)
controls = cmds.ls("*_ctrl")
for i in range(len(controls)):
self.table_wdg.insertRow(i)
controls[i] = QtWidgets.QPushButton("Button")
self.table_wdg.setCellWidget(i,0,controls[i])
controls[i].clicked.connect(self.printing)
def printing(self):
print()
I have multiple data frames to compare. My problem is the product IDs. one is set up like:
000-000-000-000
Vs
000-000-000
(gross)
I have looked on here, reddit, YouTube, and even went deep down the rabbit hole trying .join, .append, some other method I've never seen before, or even understand yet. Is there a way(or even better some documentation I can read on to learn this) to pull the Product ID from the Main excel sheet, compare it to the one(s) that should match. Then i will more than like make the in place ID across all sheets. That way I can use those IDs as the index and do a side by side compare of the ID to row data? Each ID has about 113 values to compare. That's 113 columns, but for each row if that make sense
Example: (colorful columns is main sheet that the non colored column will be compared to)
additional notes:
The highlighted yellow IDs are "unique", and I wont be changing those but instead write them to a list or something and use an if statement to ignore them when found.
Edit:
so I wrote this code which is almost perfect what I need to do with this.
It takes out the "-" which I apply to all my IDs. Just need to make a list of ID that are unique to skip over on taking away the zeros
dfSS["Product ID"] = dfSS["Product ID"].str.replace("-", "")
Then this will only list the digits up to 9 digits, except the unique IDs
dfSS["Product ID"] = dfSS["Product ID"]str[:9]
Will add the full code below here once i get it to work 100%
I am now trying to figure out how to say somethin like
lst =[1,2,3,4,5]
if dfSS["Product ID"] not in lst:
dfSS["Product ID"] = dfSS["Product ID"].str.replace("-", "").str[:9]
This code does not work but everyday I get closer and closer to being able to compare these similar yet different data frames. the lst is just an example of a 000-000-000 Product IDs in a list that I do not want to filter at all. but keep in the data frame
If the ID transformation is predictable, then one option is to use regex for homogenizing IDs. For example if the situation is just removing the first three digits, then something like the following can be used:
df['short_id'] = df['long_id'].str.extract(r'\d\d\d-([\d-]*)')
If the ID transformation is not so predictable (e.g. due to transcription errors or some other noise in the data) then the best option is to first disambiguate the ID transformation using something like recordlinkage, see the example here.
Ok solved this for every Product ID with or without dashes, #, ltters, etc..
(\d\d\d-)?[_#\d-]?[a-zA-Z]?
(\d\d\d-)? -This is for the first & second three integer sets, w/ zero or more matches and a dashes (non-greedy)
[_#\d-]? - This is for any special chars and additional numbers (non-greedy)
[a-zA-Z]? - This, not sure why, but I had to separate from the last part due to it wouldn't pick up every letter. (non-greedy)
With the above I solved everything I needed for RE.
Where I learned how to improve my RE skills:
RE Documentation
Automate the Boring Stuff- Ch 7
You can test you RE's here
Additional way to show this. Put this here to show there is no one way of doing it. RE is super awesome:
(\d{3}-)?[_#\d{3}-]?[a-zA-Z]?
I want to read in a given datalabel's text.
What I have tried:
print(plot.series[0].points[0].data_label.text_frame.text)
Snippet above tries to print the 1st series' first point which is '16' but it prints nothing.
How can I obtain what is in the datalabel?
I want to read the text in, concat something new to it and reinsert it into the data label. Something like this
dltext = plot.series[0].points[0].data_label.text_frame.text
plot.series[0].points[0].data_label.text_frame.text = dltext + "Foo"
The data_label.text_frame only contains text if you put it there explicitly. Otherwise what is rendered is a function of the value of that data-point and the settings .show_value and show_percent, etc. documented here: https://python-pptx.readthedocs.io/en/latest/api/chart.html#pptx.chart.datalabel.DataLabels
If you want to match what shows to the user you'll need to duplicate that logic.
If you wanted to accomplish that for the general case, it would take some doing because you'd need to compute the effective value of properties like DataLabel.show_value, which would require reverse-engineering the style hierarchy for that setting.
But the 95% solution would just be to assume what is showing is the value and go with that. That's the default data label, at least for bar charts (pie charts may default to percent).
I need to slice several different datasets that contain a lot of extraneous columns. It's easier for me to glance over the indices of the columns I want, and tell Python to save these columns, than type out their names one by one. For instance if I want to save only SCHOOL_DATE, STUDENT_DATE, STUDENT_P2_DATE, I'd rather tell Python to save column[3, 5:6] or something.
However, I can't find a quick way to view column names right next to their index.
Currently I just run a debugger up to a line where I create an array of my column names, then I view as array in Pycharm to quickly identify which # belongs to which name. I also tried iterating through columns to return their index position and name, but maybe because I don't know well how Python objects behave, wasn't able to get that to work.
SQLdf = pd.read_csv(desktoppath + SchoolFromSQLfilename)
cols = np.array(SQLdf.columns)
print(SQLdf.columns)
I put a debugger break on the print line. Obviously, I'd like to just print out the matches though straight into the console, than having to take a few point and click steps to view.
First do with enumerate
list(enumerate(df.columns))
[(0, 'id'), (1, 'A')]
Then pass to np.r_[3,[3:4],[5:8]]
ms word table with python
I am working with python on word tables, i am generating tables, but all of them are
auto fit window..
is it possible to change it to auto fit contents?
i had tried something like this:
table = location.Tables.Add(location,len(df)+1,len(df.columns)
table.AutoFit(AutoFitBehavior.AutoFitToContents)
but it keeps to raise errors
You want to change you table creation to use this:
//''#Add two ones after your columns
table = location.Tables.Add(location,len(df)+1,len(df.columns),1,1)
Information about why you need those variables can be read here:
http://msdn.microsoft.com/en-us/library/office/ff845710(v=office.15).aspx
But basically, the default behavior is to disable Cell Autofitting and Use Table Autofit to Window. The first "1" enables Cell Autofitting. From the link I posted above, the DefaultTableBehavior can either be wdWord8TableBehavior (Autofit disabled --default) or wdWord9TableBehavior (Autofit enabled). The number comes from opening up Word's VBA editor and typing in the Immediate Window:
?Word.wdWord9TableBehavior
Next, from the link, we see another option called AutoFitBehavior. This is defined as:
Sets the AutoFit rules for how Word sizes tables. Can be one of the WdAutoFitBehavior constants.
So now we have another term to look up. In the VBA editor's Immediate window again type:
?Word.wdAutoFitBehavior.
After the last dot, the possible options should appear. These will be:
wdAutoFitContent
wdAutoFitFixed
wdAutoFitWindow
AutoFitContent looks to be the option we want, so let's finish up that previous line with:
?Word.wdAutoFitBehavior.wdAutoFitContent
The result will be a "1".
Now you may ask, why do we have to go through all this trouble finding the numerical representations of the values. From my experience, with using pywin32 with Excel, is that you can't get the Built-in values, from the string, most of the time. But putting in the numerical representation works just the same.
Also, One more reason for why your code may be failing is that the table object may not have a function "Autofit".
I'm using Word 2007, and Table has the function, AutoFitBehavior.
So Change:
table.AutoFit(AutoFitBehaviour.AutoFitToContent)
To:
table.AutoFitBehavior(1)
//''Which we know the 1 means wd.wdAutoFitBehavior.wdAutoFitContent
Hope I got it right, and this helps you out.