2

I have QTableWidget in which chat messages (normal QLabels) should be added.

I have only one column in this table, while the alignment depends on the sender (me=left, him=right)

I know that I can add a widget into QTableWidget using:

myTable.setCellWidget(row,0,myQLabel)

This adds the label into default alignment. Now, I don't know how to make the alignment dynamic for each row.

I saw some answers doing something like this but the items were not widgets, just texts.

How to make the added QWidget goes into different alignment

eyllanesc
  • 235,170
  • 19
  • 170
  • 241
Mohammed B.
  • 160
  • 1
  • 3
  • 13

1 Answers1

1

You have to establish the alignment to the QLabel:

from PyQt5 import QtCore, QtGui, QtWidgets


class Widget(QtWidgets.QWidget):
    def __init__(self, parent=None):
        super(Widget, self).__init__(parent)

        self.m_table = QtWidgets.QTableWidget(0, 1)
        self.m_table.verticalHeader().hide()
        self.m_table.horizontalHeader().setSectionResizeMode(
            QtWidgets.QHeaderView.Stretch
        )
        self.m_lineedit = QtWidgets.QLineEdit()
        self.left_button = QtWidgets.QPushButton(
            "Left", clicked=self.on_left_clicked
        )
        self.right_button = QtWidgets.QPushButton(
            "Right", clicked=self.on_right_clicked
        )

        lay = QtWidgets.QGridLayout(self)
        lay.addWidget(self.m_table, 0, 0, 1, 2)
        lay.addWidget(self.m_lineedit, 1, 0, 1, 2)
        lay.addWidget(self.left_button, 2, 0)
        lay.addWidget(self.right_button, 2, 1)

    @QtCore.pyqtSlot()
    def on_left_clicked(self):
        self.add_label(self.m_lineedit.text(), QtCore.Qt.AlignLeft)
        self.m_lineedit.clear()
        self.m_table.scrollToBottom()

    @QtCore.pyqtSlot()
    def on_right_clicked(self):
        self.add_label(self.m_lineedit.text(), QtCore.Qt.AlignRight)
        self.m_lineedit.clear()
        self.m_table.scrollToBottom()

    def add_label(self, text, alignment):
        label = QtWidgets.QLabel(text, alignment=alignment)
        row = self.m_table.rowCount()
        self.m_table.insertRow(row)
        self.m_table.setCellWidget(row, 0, label)


if __name__ == "__main__":
    import sys

    app = QtWidgets.QApplication(sys.argv)
    w = Widget()
    w.show()
    sys.exit(app.exec_())

enter image description here

Update:

Another solution is to create a QWidget where the QLabel is placed establishing an alignment to the QLabel with respect to the QWidget.

def add_label(self, text, alignment):
    widget = QtWidgets.QWidget()
    widget.setContentsMargins(0, 0, 0, 0)
    lay = QtWidgets.QHBoxLayout(widget)
    lay.setContentsMargins(4, 0, 4, 0)
    label = QtWidgets.QLabel(text)
    lay.addWidget(label, alignment=alignment)
    row = self.m_table.rowCount()
    self.m_table.insertRow(row)
    self.m_table.setCellWidget(row, 0, widget)
eyllanesc
  • 235,170
  • 19
  • 170
  • 241
  • but this way you are aligning the text not the label it self What will it look like when the label is custom-painted one ? ( not the transparent one) – Mohammed B. Jun 04 '19 at 15:11
  • @MohamedIbrahim when a widget is established in a QTableWidget it occupies all the available size so a possible solution is the one that signals. If you are going to do a custom painting then it is your responsibility to maintain that same behavior. – eyllanesc Jun 04 '19 at 15:13
  • @MohamedIbrahim I have added another solution that no longer places the alignment in the QLabel, I think that solution is what you want. If my answer helps you, do not forget to mark it as correct, if you do not know how to do it then check the [tour] – eyllanesc Jun 04 '19 at 15:26