Error in setting QComboBox cellwidget - pyqt

I am trying to set the index of a QComboBox that was created using setCellWidget which is set inside a QTableWidget
Why is it that despite me calling the combobox using cellWidget, I got an error while trying to set its index despite its type is still a QComboBox?
for row in xrange(self.table.rowCount()):
combo = self.table.cellWidget(row, 1)
print type(combo) # returns <type 'PySide.QtGui.QComboBox'>
combo.setCurrentIndex(2)
AttributeError: 'NoneType' object has no attribute 'setCurrentIndex'

Related

Runtime error '380' Could not set the Value property. Invalid property value

I have a combobox inside of page of multipage object in a userform.
Problem comes when code runs this statement:
'Trying to set the initial value
userForm.comboBox.Value = "String"
Where "String" don't match with any of items of combo list.
I checked MatchRequired property and is set to False but the error still coming.
This works:
userForm.comboBox.Value = "Item_1"
Where Item_1 belongs to items list.
Error message is: "Runtime error '380'
Could not set the Value property. Invalid property value."
What I'm missing? Thanks in advance.

Python win32com PivotCache.CreatePivotChart() error: 'Exception occurred'

There is one other question from Sep 2017 that addresses this same problem but does not have an answer: create a pivotchart with python win32com
I have tried several approaches to get this working so I want to explain these and hopefully get some insight from someone on how to get this working. This does not appear to be a well worn path so I do not have high hopes.
Environment details:
Windows 10
Office 2013
Anaconda 3.6
I use
win32com.client.gencache.EnsureDispatch('Excel.Application')
but I can also use
win32com.client.DispatchEx('Excel.Application')
or
win32com.client.dynamic.Dispatch('Excel.Application')
Each one returns this CLSID win32com.gen_py.00020813-0000-0000-C000-000000000046x0x1x8
Each one also has the same error.
I also ran this command as per documentation here:
C:\Users\home_dir>python AppData\Local\Continuum\anaconda3\pkgs\pywin32-223-py36hfa6e2cd_1\Lib\site-packages\win32com\client\makepy.py -i "Microsoft Excel 15.0 Object Library"
Output generated from makepy.py:
Microsoft Excel 15.0 Object Library {00020813-0000-0000-C000-000000000046}, lcid=0, major=1, minor=8
>>> # Use these commands in Python code to auto generate .py support
>>> from win32com.client import gencache
>>> gencache.EnsureModule('{00020813-0000-0000-C000-000000000046}', 0, 1, 8)
This version of gencache did not work successfully:
Excel = win32com.client.gencache.EnsureModule('{00020813-0000-0000-C000-000000000046}', 0, 1, 8)
Source Data
There are 100 rows and 18 columns in a Pandas Dataframe that I write to Excel using ExcelWriter
ew = pd.ExcelWriter('c:\devworkspace\SQL-Pandas-Excel\SampleData.xlsx')
sample_data_df.to_excel(ew, sheet_name='Source Data')
ew.save()
ew.close()
Excel = win32com.client.gencache.EnsureDispatch('Excel.Application')
win32c = win32com.client.constants
wb = Excel.Workbooks.Open('c:\devworkspace\SQL-Pandas-Excel\SampleData.xlsx')
src_sheet = wb.Worksheets('Source Data')
rng_row = 100
rng_col = 18
rng_beg = src_sheet.Cells(1,2)
rng_end = src_sheet.Cells(rng_row,rng_col)
pvt_src_rng = src_sheet.Range(rng_beg, rng_end)
pvt_src_rng.Select()
pvt_src = "%s!R1C2:R%dC%d"%(src_sheet.Name,rng_row+1,rng_col+1) #add 1 for header and df index
Pivot Cache
I use PivotCaches().Create() as opposed to .Add() so I can specify Version=win32c.xlPivotTableVersion15 which is the correct version for office 2013. Otherwise it appeared to default to version 11.
pc = wb.PivotCaches().Create(SourceType=win32c.xlDatabase, SourceData=pvt_src, Version=win32c.xlPivotTableVersion15)
This change moved the dial but did not solve my problem - I am still getting an error and the chart is not getting created:
The formatting on the pivot table is enhanced when I applied this
change.
The root error code changed from -2147024809 which is "The
parameter is incorrect" To root error code -2146827284
Which it cannot translate to human readable message:
print(win32api.FormatMessage(error.excepinfo[5]))
error: (317, 'FormatMessageW', 'The system cannot find message text for message number 0x%1 in the message file for %2.')
Searching on this error code 2146827284 the discussions appear to be related to the excel object being busy. But Excel.Visible is set to 0 - also the default - so it is running in headless mode.
Adding Sheets, Creating the Pivot Table, Adding Fields is successful
These are all wrapped in try-except in the actual code - removed for brevity.
pvt_sheet = wb.Sheets.Add(After=src_sheet)
pvt_sheet.Name = 'Pivot Sheet'
pvt_rng_beg = pvt_sheet.Cells(2,2)
pvt_rng_end = pvt_sheet.Cells(2,2)
pvt_dest_rng = pvt_sheet.Range(pvt_rng_beg, pvt_rng_end)
pt = pc.CreatePivotTable(TableDestination=pvt_dest_rng,TableName='PivotTable1')
pt.AddFields(RowFields="claimant_type_desc" , ColumnFields="claim_cause_desc" )
pt.AddDataField(Field=pt.PivotFields("total_direct_payment"), Caption="Total Incurred")
I can add a sheet or a chart as the "ChartDestination" but neither option alters the outcome. I can validate that the object is getting added successfully.
#chrt_sheet = wb.Charts.Add(After=pvt_sheet)
chrt_sheet = wb.Sheets.Add(After=pvt_sheet)
chrt_sheet.Name = 'Pivot Chart'
ChartDestination argument is the only required argument the other arguments are optional: XlChartType, Left, Top, Width, Height
Docs here:
Based on examples I pass the name of the sheet or chart object as a string 'Pivot Sheet'. That should work.
pch = pc.CreatePivotChart(ChartDestination='Pivot Chart')
Because the parameter is defined as a Variant then I explicitly assign the string to a Variant object. I tried a range of different variant types but that did not yield a different outcome.
chrt_sheet_name_variant = win32com.client.VARIANT(pythoncom.VT_BYREF | pythoncom.VT_BSTR, chrt_sheet.Name)
print(chrt_sheet_name_variant.value)
print(chrt_sheet_name_variant.varianttype)
print(chrt_sheet_name_variant.__class__)
print(type(chrt_sheet_name_variant))
pch = pc.CreatePivotChart(ChartDestination=chrt_sheet_name_variant)
#Output:
#Pivot Chart
#16392
#<class 'win32com.client.VARIANT'>
#<class 'win32com.client.VARIANT'>
This is the error that is generated:
File "C:\Users\xxxxxx\AppData\Local\Temp\gen_py\3.6\00020813-0000-0000-C000-000000000046x0x1x8\PivotCache.py", line 36, in CreatePivotChart
, XlChartType, Left, Top, Width, Height
com_error: (-2147352567, 'Exception occurred.', (0, None, None, None, 0, -2146827284), None)
Thank you Boussif for finding the way on this.
Here is my working solution:
Generate a Pivot Chart from your Pivot Table
Using the Workbook object that we created earlier we can "insert" a Chart to our workbook and assign a name to our chart - name appears in the tab.
Because the Pivot Table is an object in the Pivot Cache - which is an object in the Workbook, the Chart object is added as a Pivot Chart and uses the Pivot Table as its the data.
Read the relevant documentation here:
https://learn.microsoft.com/en-us/office/vba/api/excel.workbook.charts
https://learn.microsoft.com/en-us/office/vba/api/excel.chart(object)
chrt_sheet = wb.Charts.Add()
chrt_sheet.Name = 'Pivot Chart'
Specify the Chart Type
The chart type corresponds to the same Chart Types that are available in the Excel program.
Choose from a list of enumerated types.
For example a 3D Column Chart has a value of xl3DColumn coded as follows:
win32c.xl3DColumn
Use the win32c object ew defined earlier to reference all constant values including enumerated lists.
Documented here:
https://learn.microsoft.com/en-us/office/vba/api/excel.chart.charttype
https://learn.microsoft.com/en-us/office/vba/api/excel.xlcharttype
chrt_sheet.ChartType = win32c.xl3DColumn
Set the Chart Title
The sheet object will not have a ChartTitle property until to set HasTitle Property to True
chrt_sheet.HasTitle = True
chrt_sheet.ChartTitle.Text = "Chart Title"
Set the Color Scheme
ChartColor values 10 - 26 correspond to the Change Colors menu on the DESIGN tab of the CHART TOOLS ribbon.
chrt_sheet.ChartColor = 13
Specify a Chart Layout
Layout is optional
Layouts are the same as the list of Layouts to choose from in the Excel program.
In this case they are not provided as an enumerated list. So you have to provide a number for the layout. It will generally be from 1 to 10. Layouts are different depending on the respective Chart Type. To find out which layout to choose you will need to run the Excel program and try each one. If you hover your mouse over the Layout option it will display a "Tool Tip" with the name of the Layout. For example: 'Layout 7'. You would provide the number associated with your respective layout.
you use the ApplyLayout method to choose the Layout:
ApplyLayout(Layout, Chart Type)
Documented here:
https://learn.microsoft.com/en-us/office/vba/api/excel.chart.applylayout
chrt_sheet.ApplyLayout(7, win32c.xl3DColumn)
Specify a Chart Style
Style is optional
Documentation states that 1 to 48 are valid values. However the correct range depends on which Chart Type is chosen.
Depending on the Chart Type 201 to 352 is also valid.
To get the numbers numbers that match the style selections that are available for your Chart Type:
From the Developer Tab - Run a macro
From the Chart Design Tab - Select all the styles
From the Devloper Tab - Stop running the macro
From the Developer Tab - Edit the macro
This will reveal the correct values for your case
For the 3D Column Chart Type, the range is 286 to 297
Relevant documentation here:
https://learn.microsoft.com/en-us/office/vba/api/excel.chart.chartstyle
xlChartStyle = 294
chrt_sheet.ClearToMatchStyle
chrt_sheet.ChartStyle = xlChartStyle
Chart Style Experiment
If you are curious and want to see what each one looks like then run this code
hint: Remove the comments '#'
#import time
#from time import sleep
​
#for xlChartStyle in range(286, 297):
# try:
# chrt_sheet.ClearToMatchStyle
# chrt_sheet.ChartStyle = xlChartStyle
# chrt_sheet.ChartTitle.Text = "Chart Style = "+str(xlChartStyle)
# sleep(1)
# except pythoncom.com_error as error:
# print("Chart Style = %s" % str(xlChartStyle))
​
Format Axis Labels
There are three Axis dimensions specified by the XlAxisType Enumeration
X axis = xlCategory
Y Axis = xlValue
Z Axis = xlSeriesAxis (3D Charts only)
In this example we are also removing the Z Axis Tick Labels
chrt_sheet.Axes(win32c.xlCategory).AxisTitle.Text = "X Axis Title"
chrt_sheet.Axes(win32c.xlSeries).TickLabelPosition = win32c.xlNone
chrt_sheet.Axes(win32c.xlSeries).HasTitle = True
chrt_sheet.Axes(win32c.xlSeries).AxisTitle.Text = "Z Axis Title"
chrt_sheet.Axes(win32c.xlValue).AxisTitle.Text = "Y Axis Title"

Looping through row QTableWidget

I am trying to make use of a QTableWidget in my program. When button is pressed, it should read the values of each column on first row of the QTableWidget and assign it to a variable to be used later.
Right now, it currently prints out correctly, but it then gives me an attribute error and freezes program.
Code:
def Loopthru(self):
for i in range(0, 5):
t = self.valveThicknessTable.item(0,i).text()### Returns error :AttributeError: 'NoneType' object has no attribute 'text'
print(t) ###test
I assume it has something to do with trying to loop through the columns with variable i. Any ideas why it is giving me this error?
Test program code:
https://drive.google.com/drive/folders/0BzcHlfStubD3R0VBTWZDQXp1bWc?usp=sharing
The range was wrong, it was trying to put a blank cell into a variable.

Defined Column name NOT working in simple Macro to Hide Column

I named a column: DailyReserveCol
Created simple Hide/Reveal column button
Sheets("Calculator").Columns.DailyReserveCol.Hidden = Not Column.DailyReserveCol.Hidden
But I receive the following error:
Run-time Error 424 Object Required
This works:
Sheets("Calculator").Columns("C").Hidden = Not Columns("C").Hidden
I've tried:
Columns(DailyReserveCol).Hidden
Columns("DailyReserveCol").Hidden
Error 13 Type mismatch
Am I doing it incorrectly or is this not possible?
You can use the following to toggle the visibility of a named column:
Sheets("Calculator").Range("DailyReserveCol").EntireColumn.Hidden = _
Not Sheets("Calculator").Range("DailyReserveCol").EntireColumn.Hidden

QTableView issue with selectionModel()

I have a problem with my call to QTableView.selectionModel(). I instanciate my QTableView in another class, then when I open a new project and need to fill in my view I call a function fillGrid() in which I get the data among other things. This is also where I call the selectionModel() method.
Everything goes well the first time I call it. But if I try to call it again in the same instance of the program then it gives me the following error :
TypeError: 'QItemSelectionModel' object is not callable
my function fillGrid looks like :
def fillGrid(self):
self.infos = select.getInfosProject(self.parent.db, self.parent.currentProj)
self.getData()
header = ["id","hidden","state","filename","asset-shot name","task","buffer","pass","camera","version","user","date","deps","check","comment","start frame","end frame","missing frames","edit start frame","edit end frame"]
self.model = SequenceGridModel(self.data, header, self)
self.setModel(self.model)
self.hideColumn(0)
self.hideColumn(1)
font = QtGui.QFont("Verdana", 8)
self.setFont(font)
vh = self.verticalHeader()
vh.setVisible(False)
hh = self.horizontalHeader()
hh.setStretchLastSection(True)
self.resizeColumnsToContents()
self.setSelectionBehavior(QtGui.QTableView.SelectRows)
self.selectionModel = self.selectionModel()
self.connect(self.selectionModel, QtCore.SIGNAL("selectionChanged(QItemSelection, QItemSelection)"), self.getSelection)
self.setSortingEnabled(True)
self.setEditTriggers(QtGui.QAbstractItemView.CurrentChanged)
self.viewport().installEventFilter(self)
self.setItemDelegateForColumn(13,ComboBoxDelegate(self, self.checkValues))
self.setColumnWidth(13, 64)
Any idea why this is happening ?
Thanks in advance
You've assigned your QItemSelectionModel instance to the name selectionModel, but selectionModel is a method of the QTableView class. You need to pick a new name for your selection model. See the QAbstractItemView class reference.
If you want to assign that selection model to apply to your model you need to use the setSelectionModel method.

Resources