2

I'm going to keep this question pretty general because I feel a lot of people do the same thing and I couldn't find a consice answer.

Using PyQt (4 or 5) to make a program everyone needs mainly the following lines:

from PyQt5 import QtCore, QtGui 
from PyQt5.QtWidgets import QWidget

For each widget that someone wants to create they need to write those two lines, more or less. Is there a way to (speedily) import all those lines without having to import them for each sub-widget?

To further clarify, say I have a main class MainWindow that calls upon it's child widget Child

from PyQt5 import QtCore, QtGui 
from PyQt5.QtWidgets import QWidget

from ChildWidget import Child

class MainWindow(QMainWindow):
    def __init__(self):
        super(MainWindow, self).__init__()
        widget1 = Child(self)
        ....

The file ChildWidget will then have a structure similar to

from PyQt5 import QtCore, QtGui 
from PyQt5.QtWidgets import QWidget

class Child(QWidget):
    def __init__(self, parent):
        super(Child, self).__init__(parent)
....

(And of course, imports will vary for each widget, but those two will always be there.)

I know that instead of the regular two imports in ChildWidget I can do from MainWindow import * to import everything in MainWindow but I feel that's slow because it's circular importing everything?

So my question is what's the best way to import the same functions in each widget, as the number of widgets increase, if speed is a major concern?

aseylys
  • 344
  • 1
  • 3
  • 12
  • Python imports are only done once per program. Any duplicate import statements simply look up the cached version, which incurs little overhead when used in the way you suggest. There is no need to avoid them in submodules. – user3419537 Feb 14 '17 at 13:26

1 Answers1

0

These seem to be the main possibilities (ignoring minor variations):

  1. Module namespaces:

    from PyQt5 import QtCore, QtGui, QtWidgets
    
    widget = QtWidgets.QWidget()
    
  2. Module namespaces with aliases:

    from PyQt5 import QtCore as qc, QtGui as qg, QtWidgets as qw
    
    widget = qw.QWidget()
    
  3. Star imports:

    from PyQt5.QtCore import *
    from PyQt5.QtGui import *
    from PyQt5.QtWidgets import *
    
    widget = QWidget()
    
  4. Global namespace:

    from PyQt5 import Qt
    
    widget = Qt.QWidget()
    
  5. Global star import:

    from PyQt5.Qt import *
    
    widget = QWidget()
    
  6. Individual imports:

    from PyQt5.QtCore import Qt, QTimer
    from PyQt5.QtCore import QColor, QFont
    from PyQt5.QtCore import (
        QApplication, QWidget, QVBoxLayout, QPushButton,
        QLineEdit, QListWidget,
        )
    

Option 3 pollutes the module namespace with hundreds of names that will never be used, so is generally frowned upon. Option 4 looks tempting, but if you care about the start-up time of your application, it is a poor solution, since it imports every module, including resource hogs like QtWebEngine. Option 5 combines the worst aspects of Options 3 and 4, but it does get you literally everything.

The main benefit of Option 1 (and Option 2, to a lesser extent) is that it makes it absolutely clear where the name has come from. This means it is ideal for tutorials and examples, for example. The extra clarity comes at the expense of being more verbose, but, if your editor has auto-complete, this is not much of an issue. My personal perference is for Option 6, simply because it seems to be best all-round compromise.

Community
  • 1
  • 1
ekhumoro
  • 115,249
  • 20
  • 229
  • 336