The columns of my QTableWidget do not fill in the space of the table, so that an empty space is left on the right hand-side. How to make the columns of my QTableWidget assume the maximum space so as to fill in this space?
The headers of the table have methods for controlling this:
header = table.horizontalHeader()
header.setStretchLastSection(True)
or:
header.setResizeMode(QHeaderView.Stretch)
I don't know of any method to set this property to the QTableWidget's content. However, I could use the following to get the columns to resize:
def resizeEvent(self, event):
self.setColumnWidth(0, event.size().width())
This resizes the first column only. To resize all columns, one should get all children item and apply column width / number of items.
Related
I have a python tkinter treeview that has a header font size of 12 and an row font size of 8. I have one item in the treeview. In one of the columns (lets say column 3) of the item, i have a text string that is significantly longer than the width of the column. If I use a word wrap function to warp the text string after 90 characters, the text string creates 22 rows of text in the item's column - all at font size 8.
How can I use style, height, and rowheight to set the treeview widget so that the full text in the column is displayed in the treeview and the bottom of the treeview aligns with the bottom of column 3 of the item - so that there's no white space between the bottom of the item and the bottom of the treeview? I've tried using metrics with my font to calculate the linespace and then set rowheight to linespace. But nothing seems to work.
header_font = tkfont.Font(family='TimesNewRoman', size=12)
row_font = tkfont.Font(family='TkFixedFont', size=8)
row_font.metrics()['linespace']
style = ttk.Style()
treeview.height=1
style.configure("Treeview.Heading", font=header_font, rowheight=int(12*2.5))
style.configure("Treeview", font=row_font, rowheight=(row_font.metrics()['linespace']*2.5))
Note: The treeview is in a frame using pack.
I can get the text to wordwrap using textwrap.wrap. For one item, this would result in 22 lines of text from the single string. For another item, this may result if 21 lines, etc. Note: I'm only displaying one item at a time in the treeview because of the length of the textstring. And I can set the font using a style to get it displayed in 8 point.
What I can't figure out is how to get the size of the treeview and/or frame to cut off at the bottom of the item/column so that I have no whitespace between the bottom of the item/column and the bottom of the treeview/frame, and the border around the item/columns is the bottom border of the treeview/frame.
If I set rowheight to the number of rows created from the textwrap, sometimes the bottom will cut off before the last row(s) for the item is displayed, sometimes in the middle of the row. And if I try to add a factor to the rowheight, it may be on for one row and off for other column heights.
Note: I will be loading textstrings of different length into the longest column so that's why I need to figure out a formula that will set the bottom of the treeview/frame to be the bottom of the content area/item area/column with the biggest height.
I created a table using plotly to calculate some financials, I would like to show the whole table in the graph interface (not just a few rows):
As you can see in the image, only 11 of my 30 rows are shown. I would like to show all the data of the table (all 30 rows with no scrollbar).
The code for the table is the following:
fig6 = go.Figure(data=[go.Table(
header=dict(values=list(df_table.columns),
fill_color='#d3d3d3',
align='left'),
cells=dict(values=[df_table['date'],
df_table['P/E_Ratio'],
df_table['Stock Price']],
fill_color='white',
align='left'))
])
As Juan correctly stated, adding height to fig6.update_layout() will do the trick. If you are however looking for a more dynamic workaround, you can use this function to calculate the height when input with a dataframe-
def calc_table_height(df, base=208, height_per_row=20, char_limit=30, height_padding=16.5):
'''
df: The dataframe with only the columns you want to plot
base: The base height of the table (header without any rows)
height_per_row: The height that one row requires
char_limit: If the length of a value crosses this limit, the row's height needs to be expanded to fit the value
height_padding: Extra height in a row when a length of value exceeds char_limit
'''
total_height = 0 + base
for x in range(df.shape[0]):
total_height += height_per_row
for y in range(df.shape[1]):
if len(str(df.iloc[x][y])) > char_limit:
total_height += height_padding
return total_height
You might have to play around with the other features if you have a different font_size than the default, or if you change the margin from the default. Also, the char_limit argument of the function is the other weakpoint as some characters take up more space than others, capital characters take up more space, and a single word if long can force a row to be extended. It should also be increased if the number or columns are less and vice versa. The function is written taking 4 table columns into consideration.
You would have to add fig6.update_layout(height=calc_table_height(df_table)) to make it work.
I have a QTableWidget with some of it's cells merged together using the following command:
QTableView.setSpan (self, int row, int column, int rowSpan, int columnSpan)
This gives me something like this:
Now, I am looking for a way to restore some of the previously merged cells back into original states (original rows and columns). When I looked into the documentation, there is this command called:
QTableView.clearSpans (self)
But as far as I understand, this reset all the spans that were previously set.
Is there any way to reset the span setting of just a specific cell without affecting the other merged cells? ( For example, just resetting the span setting on row 4, column 0 without affecting the other merged cells)
Is there anyway to reset the span setting of just a specific cell
without affecting the other merged cells? ( For example, just
resetting the span setting on row 4, column 0 without affecting the
other merged cells)
How to
Just re-use the function setSpan to set the span of the target cell back to 1x1.
In your example, use setSpan(4,0,1,1) to reset the span setting on row4, col0.
Example
Take your image as an example. Use setSpan(2,1,1,1) to "remove" the span setting on the target cell.
Here's the problem, if you don't use check-state column in ObjectListView, there's always this gap in every row:
Especially when you want to use a small column to show row numbers:
This is so NOT looking good, how do you make each row expand to the start?
I've just been adding an extra first empty column that has no no valueGetter and a width of 0 so it doesn't show, that way the following column starts on the left edge.
Add the following as the first column.
ObjectListView.ColumnDefn(title="", valueGetter="", maximumWidth=0)
I currently load the results of an SQL query into a TableView.
self.projectModel = QSqlQueryModel()
self.projectModel.setQuery(sql,db)
I then need to select a specific cell based on the header label (geometry). This column will move position depending on the different table that is search.
When the user clicks anywhere on the row (NOT the cell of geometry column) I would like to select the geometry column cell.
At the moment I have a this associated with the tableView
self.dlg.tableView.clicked.connect(self.cellClicked)
And in that function I have
row = self.projectModel.currentIndex()
If I use QTableView.model(row, column) to select the index, I have to speciify the row and column number. However, this would vary so I would want to do QTableView.model(row, 'geometry') however the model expects integers.
Any solutions?
thanks
So it seems all you need is a method to find a column from its header label, i.e. something like:
def columnFromLabel(self, label):
model = self.table.horizontalHeader().model()
for column in range(model.columnCount()):
if model.headerData(column, QtCore.Qt.Horizontal) == label:
return column
return -1