简体   繁体   中英

PyQt custom widget not showing

I'm new to PyQt.

I'm trying to put a QTableView in a class, so I can define it's behaviour in the class without mixing it with all the other code, but when I do so it just won't show.

Here's the code i'm learning from. It was borrowed from [ Edit table in pyqt using QAbstractTableModel ]. Readapted it slightly to use with Qt5 and moved the QTableView in a class

import sys
from PyQt5 import QtGui, QtCore
from PyQt5.QtGui import *
from PyQt5.QtWidgets import QMainWindow, QPushButton, QApplication, QVBoxLayout, QTableView, QWidget
from PyQt5.QtCore import *

# données à représenter
my_array = [['00','01','02'],
            ['10','11','12'],
            ['20','21','22']]

def main():
    app = QApplication(sys.argv)
    w = MyWindow()
    w.show()
    sys.exit(app.exec_())

# création de la vue et du conteneur
class MyWindow(QWidget):
    def __init__(self, *args):
        QWidget.__init__(self, *args)

        tablemodel = MyTableModel(my_array, self)
        table = Table(tablemodel)

        layout = QVBoxLayout(self)
        layout.addWidget(table)
        self.setLayout(layout)

# création du modèle

class Table(QWidget):
    def __init__(self, model):
        super().__init__()
        self.model = model
        self.initUI()

    def initUI(self):
        self.setMinimumSize(300,300)
        self.view = QTableView()
        self.view.setModel(self.model)


class MyTableModel(QAbstractTableModel):
    def __init__(self, datain, parent = None, *args):
        QAbstractTableModel.__init__(self, parent, *args)
        self.arraydata = datain

    def rowCount(self, parent):
        return len(self.arraydata)

    def columnCount(self, parent):
        return len(self.arraydata[0])

    def data(self, index, role):
        if not index.isValid():
            return None
        elif role != Qt.DisplayRole:
            return None
        return (self.arraydata[index.row()][index.column()])

    """
    def setData(self, index, value):
        self.arraydata[index.row()][index.column()] = value
        return True
    def flags(self, index):
        return Qt.ItemIsEditable
    """    

if __name__ == "__main__":
    main()

If I remove the class and use

table = QTableView()
table.setModel(tablemodel)

the table shows no problem.

What am I missing?

the problem: table.view has no parent. If you add self.view.show() to test to Table.initUi() , you get two widgets, MyWindow with empty table as tmoreau wrote and table.view as isolated widget.

You can either pass a parent when constructing table.view in Table.initUi()

self.view = QTableView(self) 

(then you don't need a layout) or add table.view to a layout as written by tmoreau, Then the tableview is reparented.

Removing the class has the same effect, then the tableview is added to layout.

You defined Table as a QWidget with an attribute self.view=QTableView . But you didn't define a layout on Table , so it will be displayed as an empty widget.

You either have to define a layout for Table , and add the view to it, or directly add the view to the main window's layout:

class MyWindow(QWidget):
    def __init__(self, *args):
        QWidget.__init__(self, *args)

        tablemodel = MyTableModel(my_array, self)
        table = Table(tablemodel)

        layout = QVBoxLayout(self)
        layout.addWidget(table.view)  #add view instead of table
        self.setLayout(layout)

A third way is to change the definition of Table : you could subclass QTableView instead of QWidget (code not tested):

class Table(QTableView):
    def __init__(self, model, parent):
        super(Table,self).__init__(parent)
        self.setMinimumSize(300,300)
        self.setModel(model) 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM