PYQT5 TableWidget Item Alignment [duplicate] - python

I am using PyQt based on Qt4. My Editor is PyCharm 2017.3 and my python version is 3.4. I am scraping some text from a website. I am trying to align that text to the center of the cell in a QTableWidget.
item = QTableWidgetItem(scraped_age).setTextAlignment(Qt.AlignHCenter)
self.tableWidget.setItem(x, 2,item)
Therefore while putting the item in the cell, I am trying to align it as per the documentation. The problem is that the data is not showing up.
It did show up when I removed setTextAlignment method as shown below
item = QTableWidgetItem(scraped_age)
self.tableWidget.setItem(x, 2,item)

This line of code:
item = QTableWidgetItem(scraped_age).setTextAlignment(Qt.AlignHCenter)
will not work properly, because it throws away the item it creates before assigning it to the variable. The variable will in fact be set to None, which is the return value of setTextAlignment(). Instead, you must do this:
item = QTableWidgetItem(scraped_age) # create the item
item.setTextAlignment(Qt.AlignHCenter) # change the alignment

This didn't work for me, and I'm not sure if it is because I'm using PyQt5 or it i did something wrong. I was trying to find something similar but for the whole table, and i finally stumbled upon something that worked and lets you center every cells or just one column at a time.
You have to use the delegate method:
#You're probably importing QtWidgets to work with the table
#but you'll also need QtCore for the delegate class
from PyQt5 import QtCore, QtWidgets
class AlignDelegate(QtWidgets.QStyledItemDelegate):
def initStyleOption(self, option, index):
super(AlignDelegate, self).initStyleOption(option, index)
option.displayAlignment = QtCore.Qt.AlignCenter
After implementing this in your code, you can add the following to your main window class or wherever the table is defined:
delegate = AlignDelegate(self.tableWidget)
self.tableWidget.setItemDelegateForColumn(2, delegate) #You can repeat this line or
#use a simple iteration / loop
#to align multiple columns
#If you want to do it for all columns:
#self.tableWidget.setItemDelegate(delegate)
Know this is an old question, but hope it can help someone else.

Bit late to the party but for those of you wondering how to do this on pyqt5
table = QTableWidgetItem() #QTWidgets.QTableWidgetItem() if importing QWidget from PyQt5
table.setTextAlignment(number)
setTextAlignment takes an int for the argument (alignment). Put the number in to get the result:
0:left
1:left
2:right
3:right
4:centre

Related

PyQT - QlistWidget with infinite scroll

I have a QlistWidget and I need to implement on this an Infinite Scroll, something like this HTML example:
https://scrollmagic.io/examples/advanced/infinite_scrolling.html
Basically, when the user scrolls to the last item of the list, I need to load more items and dynamically append it in the QlistWidget.
Is it possible? I didn't find any example yet.
There are likely many ways to achieve this task, but the easiest I found is to watch for changes in the scroll bar, and detect if we're at the bottom before adding more items to the list widget.
import sys, random
from PyQt5.QtWidgets import QApplication, QListWidget
class infinite_scroll_area(QListWidget): #https://doc.qt.io/qt-5/qlistwidget.html
def __init__(self):
super().__init__() #call the parent constructor if you're overriding it.
#connect our own function the valueChanged event
self.verticalScrollBar().valueChanged.connect(self.valueChanged)
self.add_lines(15)
self.show()
def valueChanged(self, value): #https://doc.qt.io/qt-5/qabstractslider.html#valueChanged
if value == self.verticalScrollBar().maximum(): #if we're at the end
self.add_lines(5)
def add_lines(self, n):
for _ in range(n): #add random lines
line_text = str(random.randint(0,100)) + ' some data'
self.addItem(line_text)
if __name__ == "__main__":
app = QApplication(sys.argv)
widget = infinite_scroll_area()
sys.exit(app.exec_())
You can directly grab scroll wheel events by overriding the wheelEvent method of QListWidget, then do the logic there which solves the potential problem of not starting out with enough list items for the scrollbar to appear. If it's not there, it can't change value, and the event can't fire. It introduces a new problem however as scrolling with the mouse wheel is not the only way to scroll the view (arrow keys, page up/down keys, etc). With the number of classes and subclasses in any gui library, it becomes imperative to get really familiar with the documentation. It's a little inconvenient that it isn't as comprehensive for python specifically, but I think the c++ docs are second to none as far as gui library documentation goes.

How can I set text of an item in QTableWidget centered both horizontally and vertically in pyqt? [duplicate]

I am using PyQt based on Qt4. My Editor is PyCharm 2017.3 and my python version is 3.4. I am scraping some text from a website. I am trying to align that text to the center of the cell in a QTableWidget.
item = QTableWidgetItem(scraped_age).setTextAlignment(Qt.AlignHCenter)
self.tableWidget.setItem(x, 2,item)
Therefore while putting the item in the cell, I am trying to align it as per the documentation. The problem is that the data is not showing up.
It did show up when I removed setTextAlignment method as shown below
item = QTableWidgetItem(scraped_age)
self.tableWidget.setItem(x, 2,item)
This line of code:
item = QTableWidgetItem(scraped_age).setTextAlignment(Qt.AlignHCenter)
will not work properly, because it throws away the item it creates before assigning it to the variable. The variable will in fact be set to None, which is the return value of setTextAlignment(). Instead, you must do this:
item = QTableWidgetItem(scraped_age) # create the item
item.setTextAlignment(Qt.AlignHCenter) # change the alignment
This didn't work for me, and I'm not sure if it is because I'm using PyQt5 or it i did something wrong. I was trying to find something similar but for the whole table, and i finally stumbled upon something that worked and lets you center every cells or just one column at a time.
You have to use the delegate method:
#You're probably importing QtWidgets to work with the table
#but you'll also need QtCore for the delegate class
from PyQt5 import QtCore, QtWidgets
class AlignDelegate(QtWidgets.QStyledItemDelegate):
def initStyleOption(self, option, index):
super(AlignDelegate, self).initStyleOption(option, index)
option.displayAlignment = QtCore.Qt.AlignCenter
After implementing this in your code, you can add the following to your main window class or wherever the table is defined:
delegate = AlignDelegate(self.tableWidget)
self.tableWidget.setItemDelegateForColumn(2, delegate) #You can repeat this line or
#use a simple iteration / loop
#to align multiple columns
#If you want to do it for all columns:
#self.tableWidget.setItemDelegate(delegate)
Know this is an old question, but hope it can help someone else.
Bit late to the party but for those of you wondering how to do this on pyqt5
table = QTableWidgetItem() #QTWidgets.QTableWidgetItem() if importing QWidget from PyQt5
table.setTextAlignment(number)
setTextAlignment takes an int for the argument (alignment). Put the number in to get the result:
0:left
1:left
2:right
3:right
4:centre

Aligning a QLineEdit inside QtTableWidget

When I try to insert new rows pressing Enter Key, all looks fine until it exceeds the limit of the window. See example below:
Disalignment example
I tried this (Widget alignment in cell pyqt), that is almost like my problem, but it not fix it.
The next code performs the error:
from PyQt5 import QtWidgets
import sys
app = QtWidgets.QApplication([])
table = QtWidgets.QTableWidget(0, 1)
def create_empty_row():
widget_completer = QtWidgets.QLineEdit()
widget_completer.returnPressed.connect(
create_empty_row)
_rows = table.rowCount()
table.setRowCount(_rows + 1)
table.setCellWidget(_rows, 0,
widget_completer)
create_empty_row()
table.show()
sys.exit(app.exec_())
I also try to fill the QTableWidget programmaticly and everything looks well and the QLineEdit are not misaligned. But I have to insert new rows by demand.
How can I align the QLineEdit inside QTableWidget?
Thanks!!
EDIT
Solved using resizeRowToContents
You aren't set the correct geometry for the different widgets. So, the problem is the height of the QTableWidget should be ScreenHeight - QLineEdit.height. With this change the QLineEdit geometry it doesn't match with the QTableWidget and should be aligned.
I hope that this help you,
Regards

not displaying old value when editing cell in a QTableWidget

I have a basic QTableWidget, created with this python code:
from silx.gui import qt
app = qt.QApplication([])
qtw = qt.QTableWidget()
qtw.show()
qtw.setColumnCount(8)
qtw.setRowCount(7)
app.exec_()
The from silx.gui import qt line is just a wrapper that finds out the installed qt wrapper (PyQt4, PyQt5 or PySide) and flattens the qt namespace.
The resulting table has a strange behavior when I edit a cell: as expected, the old text is highligted when I double-click the cell, but the unusual behavior is that the old text remains visible and the new text overlaps with the old one while I'm typing it, until I press enter or I click another cell.
I would like the old text to disappear as soon as I start typing the new one. I know it's possible, because I have an example of program that features a qTableWidget with the behavior I would like to have.
But I cannot find where in that program the cell editing behavior is altered. How can I do this?
Example of "spam" and "eggs" overlayed.
[
EDIT: the code sample without the wrapper business
from PyQt5.Qt import QApplication, QTableWidget, qVersion
app =QApplication([])
print(qVersion())
qtw = QTableWidget()
qtw.show()
qtw.setColumnCount(8)
qtw.setRowCount(7)
app.exec_()
With PyQt4, use this import (also remove the print(qVersion()) line):
from PyQt4.QtGui import QApplication, QTableWidget
My method:
class MyDelegate(QItemDelegate):
def setEditorData(self,editor,index):
editor.setAutoFillBackground(True)
editor.setText(index.data().toString())
Generally, edit behavior is controlled via QItemDelegates. Typically, this is done to provide more advanced editing, or to filter input data or perform some side effects (like update a database) when edits are made. But you can also use it to just clear the editor presented to the user when editing.
class MyDelegate(QItemDelegate):
def setEditorData(self, editor, index):
# Normally, this would set the text of the editor to the current
# value of the cell. If you do nothing here, it will be blank.
editor.clear()
qtw = QTableWidget()
delegate = MyDelegate(qtw)
qtw.setItemDelegate(delegate)
In my case, above problem comes when I set background color of QWidgetTable to transparent. When I remove the setting, there is no old data overlays the new one anymore.
Hope it helps.
You could try connecting the signal emited by QTableWidget cellClicked(int row, int column) with a slot created for clearing the entry. http://pyqt.sourceforge.net/Docs/PyQt4/new_style_signals_slots.html#connecting-disconnecting-and-emitting-signals

Is it possible to change the colour of a QTableWidget row label?

I have a class that inherits from QTableWidget and I'm wondering if it's possible to change the colour of the row label for each row in the table?
I don't want to change the colour of any of the cells or column headings.
Thanks :)
P.S. I would like each row label to have a different colour. The motivation is that I can use these colours as a key/legend as each row in the table corresponds to a differently coloured line on a plot.
EDIT: Image illustrating the elements of the table I am referring to:
Yes it is possible but only with a slight trick. With setVerticalHeaderItem of QTableWidget you can set a QTableWidgetItem even for header rows and there you can define a background brush for each row. However most of the times the background will be ignored because the actual QStyle will override it. Setting the style of the vertical header widget to a style that doesn't change the background however does the trick.
Example:
from PySide import QtGui
app = QtGui.QApplication([])
table = QtGui.QTableWidget(4, 2)
table.show()
for i in range(0, 4):
item = QtGui.QTableWidgetItem('Text')
item.setBackground(QtGui.QColor(i*50, i*30, 200-i*40))
table.setVerticalHeaderItem(i, item)
# print(QtGui.QStyleFactory.keys())
table.verticalHeader().setStyle(QtGui.QStyleFactory.create('CleanLooks'))
app.exec_()
Yes it appears that you can do so, using the QTableWidgetItem functions such as setForeground which you pass through a QBrush object that I believe you can use the QBrush's setColor function to pass it a color. The QTableWidgetItem documentation has a lot of aesthetic-based functions so it looks like what you're looking for especially since it seems to be able to target specific cells/items on the table. If you want to look more into the QTableWidget documentation itself, here's a link to that as well.

Categories

Resources