PyQt5/6 QTableWidget sütunların hizalanması

Tasarımı Designer ile yaptım orada sütun isimlerinde Tutar kısmının hizalanmasını sağa ayarladım ama programı çalıştırınca veritabanından gelen veriler sola hizalanmış olarak geliyor. Görsellik açısından diğer sütunlar sol olabilir ama Tutar kısmının sağa hizalanması lazım. Fikir ve görüşlerinizi bekliyorum. Saygılar.

Merhaba,

Her bir tablo hücresinin değeri QTableWidgetItem sınıfından oluşturuluyor. Bu sınıfın setTextAlignment isimli bir fonksiyonu var. Bu fonksiyonu, Qt.AlignRight argümanıyla çağırırsanız, tablo hücreleriniz hizalanır.

Örnek olması açısından aşağıdaki basit tablo uygulamasını inceleyebilirsiniz.

import sys

from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import QApplication, QVBoxLayout, QTableWidget, QWidget, QTableWidgetItem


class MainWindow(QWidget):
    def __init__(self):
        super().__init__()
        self.table = QTableWidget(self)
        self.table.setColumnCount(5)
        self.table.setRowCount(5)
        self.box = QVBoxLayout(self)
        self.box.addWidget(self.table)
        self.setLayout(self.box)

        for i in range(5):
            for j in range(5):
                item = QTableWidgetItem(str(i * j))
                item.setTextAlignment(Qt.AlignRight)
                self.table.setItem(i, j, item)


if __name__ == "__main__":
    app = QApplication(sys.argv)
    window = MainWindow()
    window.show()
    sys.exit(app.exec_())

Verdiğiniz örneği bir deneyeyim 6 sütun sola, 1 sütun sağa olacak şekilde denemeler yapacağım çözersem haber veririm.

import sys

from PyQt6.QtCore import Qt
from PyQt6.QtWidgets import QApplication, QVBoxLayout, QTableWidget, QWidget, QTableWidgetItem


class MainWindow(QWidget):
    def __init__(self):
        super().__init__()
        self.table = QTableWidget(self)
        self.table.setColumnCount(5)
        self.table.setRowCount(5)
        self.box = QVBoxLayout(self)
        self.box.addWidget(self.table)
        self.setLayout(self.box)

        for i in range(5):
            for j in range(5):
                item = QTableWidgetItem(str(i * j))
                print(item)
                item.setTextAlignment(Qt.AlignmentFlag.AlignRight)
                self.table.setItem(i, j, item)

PyQt6 için item.setTextAlignment i değiştirdim sizin kodda çalıştı ama benim uygulamamda çalışmadı. Ui dosyasını py dosyasına dönüştürdüğümde

        item = QtWidgets.QTableWidgetItem()
        item.setTextAlignment(QtCore.Qt.AlignmentFlag.AlignLeading|QtCore.Qt.AlignmentFlag.AlignVCenter)
        self.tableWidget.setHorizontalHeaderItem(0, item)
        item = QtWidgets.QTableWidgetItem()
        item.setTextAlignment(QtCore.Qt.AlignmentFlag.AlignLeading|QtCore.Qt.AlignmentFlag.AlignVCenter)
        self.tableWidget.setHorizontalHeaderItem(1, item)
        item = QtWidgets.QTableWidgetItem()
        item.setTextAlignment(QtCore.Qt.AlignmentFlag.AlignLeading|QtCore.Qt.AlignmentFlag.AlignVCenter)
        self.tableWidget.setHorizontalHeaderItem(2, item)
        item = QtWidgets.QTableWidgetItem()
        item.setTextAlignment(QtCore.Qt.AlignmentFlag.AlignLeading|QtCore.Qt.AlignmentFlag.AlignVCenter)
        self.tableWidget.setHorizontalHeaderItem(3, item)
        item = QtWidgets.QTableWidgetItem()
        item.setTextAlignment(QtCore.Qt.AlignmentFlag.AlignLeading|QtCore.Qt.AlignmentFlag.AlignVCenter)
        self.tableWidget.setHorizontalHeaderItem(4, item)
        item = QtWidgets.QTableWidgetItem()
        item.setTextAlignment(QtCore.Qt.AlignmentFlag.AlignLeading|QtCore.Qt.AlignmentFlag.AlignVCenter)
        self.tableWidget.setHorizontalHeaderItem(5, item)
        item = QtWidgets.QTableWidgetItem()
        item.setTextAlignment(QtCore.Qt.AlignmentFlag.AlignTrailing|QtCore.Qt.AlignmentFlag.AlignVCenter)
        self.tableWidget.setHorizontalHeaderItem(6, item)

kısımlarında hizalama işlemini en son satırdaki (6, item) kısmı Tutar kısmını ifade ediyordu sağa hizalanacaktı değiştirdim AlignmentRight yaptım değişiklik olmayınca gene designerdeki ui kodlarını uyguladım. Hizalama kodunun uygulamada değişiklik yapmamasının nedeni tahminimce Designerde QTableWidgette ki bir çok seçeneği değiştirmemden kaynaklandığını, tabloda hücre değişikliklerini, editler, sadece satırı seçmek gibi bir çok ayarda değişiklikler yaptım ondan olduğunu zannediyorum.

Sonuç olarak konuyu silebilirsiniz yada çözüldü olarak işaretleyebilirsiniz.

Bu arada, benzer işlemleri tekrar yazmak yerine for döngüsü kullanmanızı tavsiye ederim. Mesela burada 7 tane benzer özelliklere sahip widgeti aşağıda yaklaşımla da oluşturabilirsiniz.

# Widgetleri self.tableWidget'a iliştirilmiş, `items` adlı bir listede tutabilirsiniz.
self.tableWidget.items = []
# Sonra da tekrar sayısı kadar çalışan bir for döngüsü oluşturursunuz.
for index in range(7):
    # Tekrarlanacak kod parçalarını bu kısma yazarsınız.
    item = QtWidgets.QTableWidgetItem()
    item.setTextAlignment(QtCore.Qt.AlignmentFlag.AlignLeading|QtCore.Qt.AlignmentFlag.AlignVCenter)
    # Burada index'i setHorizontalHeaderItem'ın birinci parametresine
    # argüman olarak verirsiniz mesela.
    self.tableWidget.setHorizontalHeaderItem(index, item)
    self.tableWidget.items += [item]

Sayi sutunlari saga, diger sutunlar sola dayali olmalidir.

Ben videolardan bakarak yapmaya çalıştım da
veritabanindan gelen verileri sutunlara hep stringe donusturup ekliyorlardi sayisal degerler sorun cikartabilir diye. Denemesini yapıp dönüş yaparim.

Veritabanında id integer primary key, tutar kismi ise integer idi. Vt den gelen veriyi stringe donusturmeden tabloya ekledigimde onlarin sutunlari boş oluyor.

QTableWidgetItema eklenecek veriler her durumda str tipine dönüştürülerek widgete eklenmeli. Ekleme yapmadan önce veya yaptıktan sonra verinin tipine göre hizalama kuralının nasıl olması gerektiğini belirleyebilirsiniz.

Aşağıda tablo’nun satır sayısı (row) * sütun sayısı (col) kadar iterasyon (row * col) yapan bir kod bloku görüyorsunuz.

        for row in range(self.rowCount()):
            for col in range(self.columnCount()):
                cell_value = data[row][col]
                item = QTableWidgetItem(str(cell_value))
                item.setTextAlignment(
                    Qt.AlignRight if isinstance(cell_value, float) or isinstance(cell_value, int)
                    else Qt.AlignLeft
                )
                self.setItem(row, col, item)

Yukarıdaki kodlarda yer alan hizalama fonksiyonunun içine yazılan argümanı inceleyin lütfen:

item.setTextAlignment(
    Qt.AlignRight if isinstance(cell_value, float) or isinstance(cell_value, int)
    else Qt.AlignLeft
)

Bu ifade şöyle de yazılabilirdi:

if isinstance(cell_value, int) or isinstance(cell_value, float):
    alignment = Qt.AlignRight
else:
    alignment = Qt.AlignLeft
item.setTextAlignment(alignment)

Yaptığım uygulamayı PyQt5 ile devam ettim. 7 sütunlu bir tablonun son sütunu sayı içerdiğinden sağ tarafa hizalanması görünüm için iyi olacaktı ama yapamamıştım. Bugüm chatgpt ye sordum 2 kere yanlış cevap verdi ama cevabın yanlış olduğunu belirttim 3. kez kod verdi bu sefer doğru cevapladı.

import sys
from PyQt5.QtWidgets import QApplication, QMainWindow, QTableWidget, QTableWidgetItem, QHeaderView

class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()

        self.setWindowTitle("7 Kolonlu QTableWidget Örneği")
        self.setGeometry(100, 100, 600, 400)

        self.tableWidget = QTableWidget()
        self.tableWidget.setRowCount(5) # 5 satır, isteğinize göre değiştirebilirsiniz
        self.tableWidget.setColumnCount(7) # 7 sütun

        self.tableWidget.setHorizontalHeaderLabels(["Kolon 1", "Kolon 2", "Kolon 3", "Kolon 4", "Kolon 5", "Kolon 6", "Kolon 7"])

        self.populateTable()

        self.setCentralWidget(self.tableWidget)

    def populateTable(self):
        # Tabloyu doldurmak için örnek veri kullanıyoruz, istediğinize göre değiştirebilirsiniz
        for row in range(self.tableWidget.rowCount()):
            for col in range(self.tableWidget.columnCount()):
                item = QTableWidgetItem(str((row + 1) * (col + 1)))
                self.tableWidget.setItem(row, col, item)
                
                # 7. sütunu sağa hizalama
                if col == 6:
                    item.setTextAlignment(0x0082) # Qt.AlignRight | Qt.AlignVCenter

if __name__ == "__main__":
    app = QApplication(sys.argv)
    window = MainWindow()
    window.show()
    sys.exit(app.exec_())