Can't call another class

Maurizio Berti maurizio.berti at gmail.com
Mon Sep 6 20:20:00 BST 2021


Il giorno sab 4 set 2021 alle ore 16:46 paparucino <paparucino at gmail.com>
ha scritto:

> Hello, from ScriptOne I would like to run ScriptTwo so as to get a
> scrollArea with all the widgets I need. I tried to read up but without
> success.
> If I run ScriptTwo as a single script the scrollArea is displayed
> correctly.
> If I call ScriptTwo from One I get
> ================================
> Traceback (most recent call last):
>     File "/root/PycharmProjects/ForTestOnly/index.py", line 763, in
> Data_Strip
>       Ui_MainWindow.setupUi (self, self.Strip_Table, anno, month, cursor)
>     File "/root/PycharmProjects/ForTestOnly/strips.py", line 37, in setupUi
>       MainWindow.resize (900, 650) # 1700
> AttributeError: 'QObject' object has no attribute 'resize'
> ===========================================
>

That's one of the many reasons for which files generated by pyuic should
**NEVER** be modified, unless you *really* know what you're doing, which
assumes you *do* know what their classes are and how they work.

In this case, as Florian pointed out, the reason is that the setupUi
function expects a QWidget based instance (specifically, a QMainWindow in
this example), while the passed object (self.Strip_Table) is a QObject, for
which the purpose is not really clear.

          self.Strip_Table = QObject(self.Strip_tab)
          # ...
          Ui_MainWindow.setupUi(self, self.Strip_Table, anno, month, cursor)

A QObject is *not* a widget, it is the *base* class of most Qt based
objects, it's what QWidget (and therefore all subclasses) inherits from,
but it can also be used for other purposes that are not strictly related to
the UI, like an item model (not the view) or a network manager.

If you need to customize an existing ui based on some arguments, then do
not implement them in the setupUi, but create a basic UI on which elements
will be eventually added, and write a subclass that *also* inherits from
the form class, that is imported from the pyuic generated file (exactly as
it was when it was created).

from PyQt5.QtWidgets import *
from ui_mainWindow import Ui_MainWindow

class SomeWindow(QMainWindow, Ui_MainWindow):
    def __init__(self, anno, month, cursor):
        super().__init__()
        self.setupUi(self)
        self.tableAnno = QTableWidget()
        self.layout.addWidget(self.tableAnno)
        # ...

An alternative approach is to use the loadUi function of the uic module, so
that you don't need to generate the ui every time. Assuming that the ui
file is called 'somewindow.ui':

from PyQt5.QtWidgets import *
from PyQt5.uic import loadUi

class SomeWindow(QMainWindow):
    def __init__(self, anno, month, cursor):
        super().__init__()
        loadUi('somewindow.ui' self)
        self.tableAnno = QTableWidget()
        self.layout.addWidget(self.tableAnno)
        # ...

This will give you exactly the same result.

Also note that you should not call setupUi arbitrarily like a class method
using "self" for the first argument. Not only it doesn't make a lot of
sense to create a class (that inherits from QMainWindow) for which you're
not actually creating instances, but this is also wrong for two important
reasons:
- the "self" is assumed to be the ui class (the "form class") *or* the
widget used with multiple inheritance (see the first example above), not
*another* instance (it's an instance method);
- setupUi  is intended to be called only once on a "clean" widget instance,
calling it on an widget that has been already set up could potentially
overwrite some existing attributes and potentially make the whole UI
completely unusable, both for the user and programmatically;

Some other unrelated considerations:
- changing the option text and using the delegate to store data is usually
not a good idea; if you want to alter the way the data is displayed, then
you should properly set data using custom roles in the model, which can be
achieved by using item.setData(customRole, value) for a table widget item.
- function and attribute names should start with a lowercase letter, as
only classes and constants are capitalized; this ensures that you can
immediately tell them apart when reading code.
- always try to provide a minimal reproducible code, without removing parts
that might be essential and important, so that we can better understand how
your code works.

Regards,
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/20210906/bc9dfcbb/attachment.htm>


More information about the PyQt mailing list