Can't call another class

Maurizio Berti maurizio.berti at gmail.com
Fri Sep 10 05:59:24 BST 2021


Il giorno gio 9 set 2021 alle ore 14:02 paparucino <paparucino at gmail.com>
ha scritto:

> [...]
> That link only shows instructions on how to prepare a good ssce but I
> don't see any references to a mailing list


What Florian meant was that you should use the instructions on that website
and then post to *this* mailing list.


Il giorno mer 8 set 2021 alle ore 16:47 paparucino <paparucino at gmail.com>
ha scritto:

> I never edit the ui file. I keep it as a base and eventually I create many
> .py files depending on how the debug goes. I know that it is confusing and
> that I fill the dir with files but sometimes I start from an idea and as
> everything evolves I can change my mind and therefore I have a base plus a
> certain series of more or less functional back ups
>
Creating multiple UI files for the same interface is not an issue, as long
as it's only done for UX purposes (aesthetic or design).

The example is perfect, but if I don't have an entry point for my tables in
> the ui-> py file, I don't know where to start. I created a ui file with
> scrollArea containing a number of tables, transformed it into py, I
> "analyzed the code, I deleted all the tables by inserting mine, with the
> necessary changes. Result: I get what I expect. Then the problems begin.
>

And that's an important hint, because it means that the whole concept
begins with the wrong premise. If you have to dynamically create tables,
those tables should *not* exist in the first place.

The UI should be like a "dough" for a cake, like those you buy in a store.
It has been made using basic ingredients, like eggs, flour, yeast and milk.
Then you can add anything you want, fruit, chocolate, nutella, etc.
But if you want to make a cake using wholemeal flour or lactose-free milk,
you cannot remove them from that dough.
And if you want to create a "convenience dough" for a cake that could
possibly have normal milk or lactose-free milk, then you have to create a
basic dough that has **no** milk at all.

I've prepared a basic example of what you might want to achieve. There's a
basic QMainWindow with an *empty* scroll area (but an existing layout), and
the code that allows you to create as many tables as you want.

UI code (tables.ui):

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>MainWindow</class>
 <widget class="QMainWindow" name="MainWindow">
  <property name="windowTitle">
   <string>MainWindow</string>
  </property>
  <widget class="QWidget" name="centralwidget">
   <layout class="QVBoxLayout" name="verticalLayout">
    <item>
     <layout class="QHBoxLayout" name="horizontalLayout_2">
      <item>
       <widget class="QPushButton" name="addTableButton">
        <property name="text">
         <string>Add table</string>
        </property>
       </widget>
      </item>
      <item>
       <spacer name="horizontalSpacer">
        <property name="orientation">
         <enum>Qt::Horizontal</enum>
        </property>
        <property name="sizeHint" stdset="0">
         <size>
          <width>40</width>
          <height>20</height>
         </size>
        </property>
       </spacer>
      </item>
     </layout>
    </item>
    <item>
     <widget class="QScrollArea" name="scrollArea">
      <property name="widgetResizable">
       <bool>true</bool>
      </property>
      <widget class="QWidget" name="scrollAreaWidgetContents">
       <property name="geometry">
        <rect>
         <x>0</x>
         <y>0</y>
         <width>542</width>
         <height>696</height>
        </rect>
       </property>
       <layout class="QHBoxLayout" name="horizontalLayout"/>
      </widget>
     </widget>
    </item>
   </layout>
  </widget>
  <widget class="QMenuBar" name="menubar">
   <property name="geometry">
    <rect>
     <x>0</x>
     <y>0</y>
     <width>558</width>
     <height>24</height>
    </rect>
   </property>
  </widget>
  <widget class="QStatusBar" name="statusbar"/>
 </widget>
 <resources/>
 <connections/>
</ui>


and the python code, which extends the TableWidget class of my previous
message:


from string import ascii_uppercase as letters
from PyQt5 import QtCore, QtWidgets, uic

Days = 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'


class TableWidget(QtWidgets.QTableWidget):
    def sizeHintForColumn(self, column):
        model = self.model()
        header = self.verticalHeader()
        opt = self.viewOptions()
        spanned = False
        hint = 0
        for row in range(model.rowCount()):
            if header.isSectionHidden(row):
                continue
            if self.columnSpan(row, column) > 1:
                spanned = True
            else:
                index = model.index(row, column)
                opt.index = index
                delegate = self.itemDelegate(index)
                hint = max(hint, delegate.sizeHint(opt, index).width())
        if spanned and hint:
            return hint
        return super().sizeHintForColumn(column)

    def minimumSizeHint(self):
        return QtCore.QSize(self.sizeHint().width(),
super().minimumSizeHint().height())

    def sizeHint(self):
        width = height = self.frameWidth()
        for column in range(self.columnCount()):
            width += self.sizeHintForColumn(column) + 1
        for row in range(self.rowCount()):
            height += self.sizeHintForRow(row) + 1
        return QtCore.QSize(
            width + self.verticalScrollBar().sizeHint().width(),
            height)


class MainWindow(QtWidgets.QMainWindow):
    def __init__(self, tableCount=1):
        super().__init__()
        uic.loadUi('tables.ui', self)
        self.addTables(tableCount)
        self.addTableButton.clicked.connect(lambda: self.addTable())

    def addTables(self, count):
        for i in range(count):
            self.addTable()

    def addTable(self, tableName=None):
        table = TableWidget()
        if tableName is not None:
            # get data from database
            pass
        else:
            data = [['Header for table {}'.format(
                self.scrollAreaWidgetContents.layout().count() + 1)]]
            data += [(i + 1, Days[i % 7], l * 8) for i, l in
enumerate(letters)]
        rowCount = len(data)
        columnCount = 0
        for rowData in data:
            columnCount = max(columnCount, len(rowData))
        table.setRowCount(rowCount)
        table.setColumnCount(columnCount)
        table.horizontalHeader().setSectionResizeMode(
            QtWidgets.QHeaderView.ResizeToContents)
        table.horizontalHeader().hide()
        table.verticalHeader().hide()
        for row, rowData in enumerate(data):
            for column, value in enumerate(rowData):
                item = QtWidgets.QTableWidgetItem()
                item.setData(QtCore.Qt.DisplayRole, value)
                table.setItem(row, column, item)
            if column == 0:
                # assume that there's only one item in this row, and that
it is a
                # header, so we set its row span
                table.setSpan(row, 0, 1, columnCount)
                item.setData(QtCore.Qt.TextAlignmentRole,
QtCore.Qt.AlignCenter)

        # it's usually better to add complex widgets to layouts *after*
their
        # contents have been declared, especially when creation is done at
runtime
        self.scrollAreaWidgetContents.layout().addWidget(table)


if __name__ == '__main__':
    import sys
    app = QtWidgets.QApplication(sys.argv)
    tableCount, _ = QtWidgets.QInputDialog.getInt(
        None, 'Create tables', 'Insert the table count', 3, 1)
    mainWindow = MainWindow(tableCount)
    mainWindow.show()
    sys.exit(app.exec_())

I strongly suggest you to carefully study the above code, look up every
function you don't know and do some testing afterwards in order to better
understand how it works.
Open the UI file in Designer and check all the properties of its children,
especially the scroll area and its content.

Good luck!
Maurizio

-- 
È difficile avere una convinzione precisa quando si parla delle ragioni del
cuore. - "Sostiene Pereira", Antonio Tabucchi
http://www.jidesk.net
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://www.riverbankcomputing.com/pipermail/pyqt/attachments/20210910/74ccdc8c/attachment-0001.htm>


More information about the PyQt mailing list