How to use `ListCtrl` on wxpython - python

How can I append row and it's corresponding data into ListCtrl.
I've just finished how to use TreeCtrl(Relatively easier than ListCtrl), it shows me a clear usage of matching single GUI object and data. But ListCtrl dose not.
How can I append or insert single row with it's corresponding data.
How can I access row and it's data
How can I manipulated them (Editing data/row, Deleting data/row)
Can you explain summary of them? Thank you.
I know my question is so simple and I can get about this from doc somewhat.
I read docs, but still I got no clue

I know that wxPython docs are retarded and gives no much help, here is some quick tips below,
i added explanations in comments:
# create new list control
listctrl = wx.dataview.DataViewListCtrl( my_panel, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.dataview.DV_SINGLE )
# setup listctrl columns
listctrl.AppendTextColumn('first name', width=220) # normal text column
listctrl.AppendBitmapColumn('my images', 0, width=35) # you can add images in this col
listctrl.AppendProgressColumn('Progress', align=wx.ALIGN_CENTER) # a progress bar
listctrl.SetRowHeight(30) # define all rows height
# add data, note myList is a list or tuple contains the exact type of data for each columns and same length as col numbers
listctrl.AppendItem(myList)
# to modify an entry "a single cell located at row x col"
listctrl.SetValue(myNewValue, row, column)

this is what works for me:
import wx
il_icons = wx.ImageList(16, 16, mask=True, initialCount=2)
il_icons.Add(wx.Bitmap('icon01.png'))
il_icons.Add(wx.Bitmap('icon02.png'))
lc_list = wx.ListCtrl(self, wx.ID_ANY, style=wx.LC_REPORT | wx.LC_SINGLE_SEL | wx.LC_EDIT_LABELS | wx.LC_VRULES, name='lc_list')
lc_list.AssignImageList(il_icons, which=wx.IMAGE_LIST_SMALL)
lc_list.AppendColumn('col01', format=wx.LIST_FORMAT_LEFT, width=64)
lc_list.AppendColumn('col02', format=wx.LIST_FORMAT_RIGHT, width=64)
lc_list.Append(('item01',100))
lc_list.Append(('item02',200))
lc_list.SetItemColumnImage(0,0,0)
lc_list.SetItemColumnImage(1,0,1)
lc_list.Bind(wx.EVT_LIST_ITEM_SELECTED, OnItemSelected)
lc_list.Show(True)

Related

MariaDB BLOB data format in Power BI vs. Python conversion

I have a MariaDB Table containing a MEDIUMBLOB Column. There are several entries in this table corresponding to one photo each.
When querying the data to PowerBI using the MariaDB connector, I get the Data in the format "Binary"
However, when querying the same data in Python (IDE or PowerBI) the format is different:
The bigger picture is to use this code to split the image in bits as PBI has a character-limit on their data elements:
Source = MariaDB.Contents("XXX.XXX.XXX.XXX:YYYY", "ZZZZZ"),
Query1= Source{[Name="Query1",Kind="Table"]}[Data],
#"Removed Top Rows" = Table.Skip(qc_westernblot_Table,1),
//Remove unnecessary columns
RemoveOtherColumns = Table.SelectColumns(#"Removed Top Rows",{"picture", "batchname"}),
//Creates Splitter function
SplitTextFunction = Splitter.SplitTextByRepeatedLengths(30000),
//Converts table of files to list
ListInput = Table.ToRows(RemoveOtherColumns),
//Function to convert binary of photo to multiple
//text values
ConvertOneFile = (InputRow as list) =>
let
BinaryIn = InputRow{0},
FileName = InputRow{1},
BinaryText = Binary.ToText(BinaryIn, BinaryEncoding.Base64),
SplitUpText = SplitTextFunction(BinaryText),
AddFileName = List.Transform(SplitUpText, each {FileName,_})
in
AddFileName,
//Loops over all photos and calls the above function
ConvertAllFiles = List.Transform(ListInput, each ConvertOneFile(_)),
//Combines lists together
CombineLists = List.Combine(ConvertAllFiles),
//Converts results to table
ToTable = #table(type table[Name=text,Pic=text],CombineLists),
//Adds index column to output table
AddIndexColumn = Table.AddIndexColumn(ToTable, "Index", 0, 1)
in
AddIndexColumn
As I am a beginner on this topic, I am confident there is a straight-forward conversion missing here but I couldn't figure it out so far myself.
I greatly appreciate any help. Thank you!
What are you planning to do with this data? PBI doesn't support binary data although you can see it in Power Query. It must be converted to something else before it can be loaded to the PBI data model.
I suspect the Python version is just the binary already converted to text. If you click the two arrows in the top right of the picture column for the PBI version, do you not get the same output?

How to freeze first column using Openpyxl

I am using the following code to freeze the first column of my excel sheer generated using openpyxl. But this is not working and showing me an error.
dim_holder = DimensionHolder(worksheet=worksheet)
for col in range(worksheet.min_column, worksheet.max_column + 1):
dim_holder[get_column_letter(col)] = ColumnDimension(
worksheet, min=col, max=col, width=20)
# worksheet.column_dimensions.group(2, 10)
dim_holder['A'] = ColumnDimension(
worksheet, min=1, max=1, width=35)
worksheet.column_dimensions = dim_holder
worksheet.freeze_panes = 'A'
How can I freeze the entire first column, so that it will be sticky when I do horizontal scrolling ?
As not all code is present, but you have mentioned that you are using openpyxl, I am going to assume that. To freeze panes, you need to give the cell. That will freeze the panes above and to the left of the same. So, when you give A, it will not help, need to change it to B1 instead. A simple example is given below.
wb=openpyxl.load_workbook('YourFile.xlsx')
ws=wb['YourSheet']
c = ws['B1'] ## Freeze everything to left of B (that is A) and no columns to feeze
ws.freeze_panes = c
wb.save('YourFile.xlsx')

Python pptx - creating chart with multiple categories?

is it possible to create a chart in python with multiple categories?
For example:
I copy pasted this in powerpoint, loaded it and tried this:
presentation.slides[0].shapes[0].chart.plots[0].categories.flattened_labels
which gave me all the labels in a tuple format -->
(('Oct-2019', 'Advertiser'),('Oct-2019','25th percentile), etc ...)
if I try printing :
presentation.slides[0].shapes[0].chart.plots[0].categories[i]
for i in 0 to 3
I get the values 'Advertiser','25th percentile' etc, but I can't find a way to access the 'Oct-2019' value.
When creating the ChartData, I saw that I can also add_category, but this adds the label to the categories I'm currently accessing (e.g. Advertiser, 25th percentile, etc), but I would like to add 'Nov 2019' which is in another hierarchy level.
This is a bit of a roundabout way of asking if anyone has created a multi-category chart with python pptx, and how they would do it from the chartdata level/what this would look like.
Thank you!
#data
pivot_digital_monthly_imp_laydown = pd.pivot_table(digital_monthly_imp_laydown, values='Original Value', index=['Year','Month'],
columns=['Campaign'], aggfunc=np.sum,fill_value=0,sort=False).reset_index().rename_axis(None, axis=1)
pivot_digital_monthly_imp_laydown.Year=pivot_digital_monthly_imp_laydown.Year.astype(str)
#inserting Impressions laydown in slide
prs=input_ppt
digital_monthly_imp_laydown_chart = prs.slides[3].shapes[6].chart
digital_monthly_imp_laydown_data =CategoryChartData()
#multilevel Categories
cat=list(pivot_digital_monthly_imp_laydown['Year'])
subcat=list(pivot_digital_monthly_imp_laydown['Month'])
b={}
for i,j in zip(cat,subcat):
key=str(i)
b.setdefault(key,[])
b[key].append(j)
main_cat=list(b.keys())
for i in range(len(main_cat)):
ear=digital_monthly_imp_laydown_data.add_category(str(main_cat[i]))
for sub in b[main_cat[i]]:
ear.add_sub_category(str(sub))
#add series data
for col in pivot_digital_monthly_imp_laydown.columns[2:]:
new = list(pivot_digital_monthly_imp_laydown[col])
digital_monthly_imp_laydown_data.add_series(str(col),new)
new=[]
digital_monthly_imp_laydown_chart.replace_data(digital_monthly_imp_laydown_data)
#saving
prs.save("./Output/Sub Brand Output.pptx")

Save Holoviews as interactive html

I have a Holoviews code with the intent of saving the output as .html. The below works fine i.e. html is genereated and tags are renders but filters don't work. What am I doing wrong?
def load_data(country, lan_name, **kwargs):
df = subset
if country != 'ALL':
df = df[(df.country == country)]
if lan_name != 'ALL':
df = df[(df.lan_name == lan_name)]
table = format_chars(df['term'], df['hex'])
#hv.Table(df, ['country', 'lan_name'], [], label='Data Table')
layout = (table).opts(
opts.Layout(merge_tools=False),
opts.Div(width=700, height=400),
)
return layout
methods = ['ALL'] + sorted(list(subset['country'].unique()))
models = ['ALL'] + sorted(list(subset['lan_name'].unique()))
dmap = hv.DynamicMap(load_data, kdims=['country', 'lan_name']).redim.values(country=methods, lan_name=models)
hv.save(dmap, 'output.html', backend='bokeh')
By "filters" it sounds like you mean the widgets that select along the country and lan_name dimensions. Each time you select a new value of a widget, a DynamicMap calls the Python function that you provide it (load_data here) to calculate the display (which is what makes it "Dynamic"). There is no Python process available when you have a static HTML file, so the display will never get updated in that case.
To make some limited functionality available in a static HTML file, you can convert the DynamicMap to a HoloMap that contains all the displayed items for some specific combinations of widget values (http://holoviews.org/user_guide/Live_Data.html#Converting-from-DynamicMap-to-HoloMap). The resulting parameter space can quickly get quite large, so you will often need to select a feasible subset of values for this to be a practical option.

How to delete row/rows from a qtableview in pyqt?

I am using QStandardItemModel for my qtableview.
import ui_my_viewlogs
import os
from PyQt4 import QtCore, QtGui
class my_viewlogs(QtGui.QDialog, ui_my_viewlogs.Ui_viewlogs):
def __init__(self):
super(my_viewlogs, self).__init__()
self.setupUi(self)
self.model = QtGui.QStandardItemModel()
self.tableView.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
self.header_names = ['abc', 'def', 'ghi', 'kjl', 'mno', 'pqr']
self.model.setHorizontalHeaderLabels(self.header_names)
self.tableView.verticalHeader().setVisible(False)
self.tableView.setShowGrid(False)
self.selectionModel = self.tableView.selectionModel()
self.tableView.customContextMenuRequested.connect(self.open_menu)
self.tableView.setModel(self.model)
self.tableView.setSelectionBehavior(QtGui.QAbstractItemView.SelectRows)
def open_menu(self, position):
menu = QtGui.QMenu()
remove_selected_item_icon = QtGui.QIcon()
remove_selected_item_icon.addPixmap(QtGui.QPixmap(":/images /Images/deleteSelected.png"), QtGui.QIcon.Normal, QtGui.QIcon.On)
remove_selected_item = menu.addAction(remove_selected_item_icon, "Remove selected item(s) ")
if action == remove_selected_item:
model = self.model
indices = self.tableView.selectionModel().selectedRows()
for index in sorted(indices):
model.removeRow(index.row(), QtCore.QModelIndex())
here when I am trying to delete the row selected(i.e. model.removeRow() ) I am getting a error" TypeError: argument 1 of QAbstractItemModel.removeRow() has an invalid type".
I have searched a lot for the correct way of deleting a selected row/rows in qtableview of pyqt. However, I am not able to delete the selected row/rows.
Can you please share a sample code for deleting selected row/rows in qtableview of pyqt?
the method model.removeRow(index.row()) removes the row selected.
model = self.model
indices = self.tableView.selectionModel().selectedRows()
for index in sorted(indices):
model.removeRow(index.row())
in the indices variable we get the selected row, then we delete the row.
For deleting multiple rows in our selection of tableview:
index_list = []
for model_index in self.tableView.selectionModel().selectedRows():
index = QtCore.QPersistentModelIndex(model_index)
index_list.append(index)
for index in index_list:
self.model.removeRow(index.row())
In C++:
QModelIndexList indices = myTable->selectionModel()->selectedRows();
for (int i=indices.count()-1; i>=0; --i)
{
QModelIndex index = indices.at(i);
myTable->removeRow(index.row());
}
You have to go from the bottom to the top of the list or your indexing will be screwed up.
This works just fine for me using the reversed().
indices = self.tag_table.selectionModel().selectedRows()
# Must delete in reverse order
for each_row in reversed(sorted(indices)):
self.tag_table.removeRow(each_row.row())
If someone is still looking for an answer after implementing Anuj Bhasin's answer because the above solution will not work in many cases as expected.
Reason:
When you delete row index (for example [0,1,2]), and you start to delete from 0 -> 1 -> 2, then only row 0 and row 2 will be deleted!
Deleting the First item will shift the remaining rows up, making row 1 and row 2 as row 0 and row 1 respectively, thus when you next delete row 1, row 2 (previously) will be deleted as it is now row 1.
I have a solution to this:
Pass rows you want to delete for example from 5 rows delete [0,3]
def setSel(selected: List[int], table_widget: QTableWidget):
"""
Select all rows for the given index range
"""
table_widget.setSelectionMode(QAbstractItemView.MultiSelection)
for i in selected:
table_widget.selectRow(i)
then call remove_row_all_table() with table_widget:QTableWidget as parameter
def remove_row_all_table(table_widget):
"""
Select and Delete rows from table widget
"""
table_widget: QTableWidget
selected_rows = table_widget.selectionModel().selectedRows()
if selected_rows:
row_indices = []
for row_index in selected_rows:
row_indices.append(row_index.row())
row_indices.sort(key=lambda x: -1 * x)
print(row_indices)
for row in row_indices: # sorted in descending order
print(f"row count:{table_widget.rowCount()}, deleting index:{row}")
table_widget.removeRow(row)
print()
Summary of this answer is: You have to turn on MultiSelection mode and Delete in reverse order, i.e. from higher index to lower index, so that the dependency that I mentioned at the beginning of the answer does not occur.
I know this is a bit of an older question, but I think this is more concise and does the trick.
def delete_record1(self, model, view):
"""Delete rows with currently selected cells and/or selected rows of the model"""
rows = [model_index.row() for model_index in view.selectedIndexes()]
rows.sort(reverse=True)
for i in rows:
model.removeRow(i)
model.submitAll()
model.select()
Can anybody advise what the pitfalls of this approach is?

Categories

Resources