如何使用 PySide6 避免循环导入

问题描述 投票:0回答:1

原始文件,mre.py

import sys

from PySide6.QtCore import (Qt, QSize, QPoint, QRect,
                            QEvent, QObject,
                            Signal, SignalInstance, Slot,
                            )

from PySide6.QtGui import (QResizeEvent, QMoveEvent,
                           QFocusEvent, )

from PySide6.QtWidgets import (QWidget, QPushButton, QLabel,
                               QHBoxLayout, QVBoxLayout, 
                               QMainWindow, QApplication,
                               QSizePolicy, QLayout, QLayoutItem
                               )

class CustomEventFilter(QObject):
    """Installs eventFilter obj on a widget.

    Args:
        widget: QWidget instance
    """
    def __init__(self, widget: QWidget):
        # if you don't pass widget to be a parent of this evFilter,
        # then the event filter will most likely be destroyed.
        super().__init__(widget)   
        
        # set protected variable
        self._widget = widget
        
        # Install this filterObj instance on the given widget
        self.widget.installEventFilter(self)

    # Encapsulation stuff
    @property
    def widget(self):
        return self._widget    

    def eventFilter(self, obj: QWidget, event: QEvent):
        match (event.type()):
            case _:
                # For all events other than move and resize, handle according to QObject built-in eventFilter().
                return super().eventFilter(obj, event)

class MeatballEventFilter(CustomEventFilter):
    def __init__(self, widget, sig: Signal = None):
        super().__init__(widget)
        self._sig = sig

    @property
    def widget(self) -> QWidget:
        return self._widget
    
    @property
    def sig(self) -> SignalInstance:
        return self._sig
    
    def eventFilter(self, obj: QWidget, event: QEvent):
        match (event.type()):
            case QEvent.FocusOut:
                # print("Lost focus!\nReason: {}".format(event.reason()))
                # if event.reason() == Qt.FocusReason.ActiveWindowFocusReason:
                #     return True

                # self.sig.emit(self.widget)
                return True
            case QEvent.FocusIn:
                # print("Gained focus!")
                return True
            case _:
                return super().eventFilter(obj, event)

class WindowEventFilter(CustomEventFilter):
    def __init__(self, widget):
        super().__init__(widget)

    @property
    def widget(self):
        return super().widget
    
    def eventFilter(self, obj: QWidget, event:QEvent):
        match (event.type()):
            case QEvent.MouseButtonRelease:
                #TODO
                print("mouse window!")
                sub: SubBox = obj.findChild(SubBox)

                evFilter: SubBoxEventFilter = sub.findChild(SubBoxEventFilter)
                return evFilter.eventFilter(sub, event)

                # return sub.eventFilter(sub, event)  # this doesn't work.
            case _:
                return super().eventFilter(obj, event)

class SubBoxEventFilter(CustomEventFilter): 
    """blah blah blah
    """
    def __init__(self, widget: QWidget):
        super().__init__(widget)

    @property
    def widget(self):
        return super().widget

    def eventFilter(self, obj: QObject, event:QEvent):
        # print(type(obj))
        match (event.type()):
            case QEvent.Resize:   # TODO
                # Won't matter for final product(I think?) but for test purposes will be implemented here
                
                return True
            
            case QEvent.Move:
                # Check meatball
                print("Sub moving meatball!")
                if obj.findChild(TestSongMeatball):
                    meatball: TestSongMeatball = obj.findChild(TestSongMeatball)
                    meatball.findPos()
                    return True
                
                # Return True to notify app that moving took place.
                return True
            
            case _:
                # For all events other than move and resize, handle according to QObject built-in eventFilter().
                return super().eventFilter(obj, event)


class TestSong(QWidget):

    # Create signals to relay info about meatball
    meatballCreated = Signal(QWidget, name="meatballCreated")
    meatballDestroyed = Signal(QWidget, name="meatballDestroyed")

    def __init__(self):
        super().__init__()

        self.setStyleSheet("background-color: blue")

        # Init layout on widget
        layout = QHBoxLayout(self)

        # Crate widgets
        label = QLabel("Label")
        meatball = TestSongButton("Meatball button")

        layout.addWidget(label)
        layout.addWidget(meatball)

        # connect clicked signal to relay into a meatballCreate signal, passing this widget
        # as a param
        meatball.clicked.connect(
            lambda checked: self.meatballCreated.emit(self))  
    
class TestSongButton(QPushButton):
    def __init__(self, text):
        super().__init__(text)

        self.setStyleSheet("background-color: purple")
    
class TestSongMeatball(QWidget):
    def __init__(self, songWidget: TestSong, parent=None):
        super().__init__(parent)

        # Set reference to song widget
        self._songWidget = songWidget

        self.setStyleSheet("background-color: red")

        # Create sizePolicy obj, init with horizontal and vertical preferences
        policy = QSizePolicy()
        policy.setHorizontalPolicy(QSizePolicy.Policy.Preferred)
        policy.setVerticalPolicy(QSizePolicy.Policy.Preferred)

        # Set policy, min and max size of the widget.
        self.setSizePolicy(policy)
        self.setMinimumSize(QSize(70, 50))
        self.setMaximumSize(QSize(160, 80))

        fPolicy = Qt.FocusPolicy(Qt.StrongFocus)
        self.setFocusPolicy(fPolicy)

        # Assign layout to widget
        layout = QVBoxLayout(self)
        
        # Add demo label for clarity
        text = QLabel("Meatball Menu")
        layout.addWidget(text)

    @property
    def songWidget(self):
        return self._songWidget

    def findPos(self):
        p = self.parent()
        # First check that there is a song meatball created as a child of monitorObj (_widget)
        if p.findChild(TestSongMeatball):
            # find song item and store its position
            item_pos = self.songWidget.pos()

            # Type hint for Python intellisense purposes
            # find button within song item and store its position
            button: TestSongButton = self.songWidget.findChild(TestSongButton)
            button_pos = button.pos()

            # since item sits inside SubBox, the meatball will have the same geometry starting point (I think?)
            # So to find the button we need to add them
            x,y = item_pos.x(), item_pos.y()
            nx,ny, = button_pos.x(), button_pos.y()

            # Add co-ordinates to get button's top left corner
            meatball_pos = QPoint(x+nx,y+ny)
            
            # Move to new position, then allow QT to find correct size, using SizePolicy.
            self.move(meatball_pos)
            self.adjustSize()

        return

    def sizeHint(self):
        return QSize(80,60)

class SubBox(QWidget):
    def __init__(self):
        super().__init__()

        self.setStyleSheet("background-color: green")

        # Create and apply layout
        layout = QVBoxLayout(self) 

    @Slot()
    def addWid(self, item: TestSong):
        if self.findChild(TestSongMeatball):
            print("Meatball already present.")
            return
        
        # Create meatball widget
        meatball = TestSongMeatball(item, self)
        evFilter = MeatballEventFilter(meatball, item.meatballDestroyed)

        meatball.findPos()
        meatball.show()  # show meatball
        meatball.setFocus()

        return

    @Slot()
    def remWid(self, meatball: TestSongMeatball):
        meatball.deleteLater()
        meatball = None

        return

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

        window_widget = QWidget()
        window_layout = QVBoxLayout(window_widget)

        winFilter = WindowEventFilter(window_widget)

        fPolicy = Qt.FocusPolicy(Qt.StrongFocus)
        self.setFocusPolicy(fPolicy)

        #TODO: put this into a function
        # Give total layout a label
        window_layout.addWidget(QLabel("Window"))
        
        # Create sub-box
        sub = SubBox()

        # Install event filter to SubBox
        subFilter = SubBoxEventFilter(sub)

        test_widget = TestSong()

        sub.layout().addWidget(test_widget)
        
        window_layout.addWidget(sub)
        
        test_widget.meatballCreated.connect(
            lambda item: sub.addWid(item))
        
        test_widget.meatballDestroyed.connect(
            lambda meatball : sub.remWid(meatball))
        
        # set window as central
        self.setCentralWidget(window_widget)
        
def main():
    # Create app
    app = QApplication(sys.argv)
    window = TestWindow()
    window.show()
    app.exec()

if __name__ == '__main__':
    main()

我想知道分割这段代码的最佳方法。到目前为止,我已尝试将

CustomEventFilter
MeatballEventFilter
SubBoxEventFilter
WindowEventFilter
类移动到自己的文件中,称为
EvFilter.py
。然后将
SubBox
TestSongMeatball
导入到
EvFilter.py
中,以允许
QWidget.findChild()
找到有问题的小部件。

这给我留下了两个文件,

EvFilter.py
mre.py
,前者包含
CustomEventFilter
的所有子类,并将
SubBox
TestSongMeatball
导入其中;后者包含
TestSong
TestSongButton
TestSongMeatball
SubBox
TestWindow
main()
,然后导入
CustomEventFilter
的所有子类。

我可以清楚地看到这将如何创建循环导入,并尝试通过我在网上找到的修复程序来解决该问题。

当尝试导入整个文件然后访问各个类时,例如:

import mre

sub = obj.findChild(mre.SubBox)

findChild()
函数将返回 None。

显然我需要重组程序以避免这个缺陷,但不知道这样做的最佳方法。那,或者我需要在不使用

QWidget
的情况下找到
findChild()
的孩子。

EvFilter.py

from PySide6.QtCore import (QEvent, QObject,
                            Signal, SignalInstance, 
                            )

from PySide6.QtWidgets import (QWidget, )

from mre import (TestSongMeatball, SubBox, )

class CustomEventFilter(QObject):
    """Installs eventFilter obj on a widget.

    Args:
        widget: QWidget instance
    """
    def __init__(self, widget: QWidget):
        # if you don't pass widget to be a parent of this evFilter,
        # then the event filter will most likely be destroyed.
        super().__init__(widget)   
        
        # set protected variable
        self._widget = widget
        
        # Install this filterObj instance on the given widget
        self.widget.installEventFilter(self)

    # Encapsulation stuff
    @property
    def widget(self):
        return self._widget    

    def eventFilter(self, obj: QWidget, event: QEvent):
        match (event.type()):
            case _:
                # For all events other than move and resize, handle according to QObject built-in eventFilter().
                return super().eventFilter(obj, event)

class MeatballEventFilter(CustomEventFilter):
    def __init__(self, widget, sig: Signal = None):
        super().__init__(widget)
        self._sig = sig

    @property
    def widget(self) -> QWidget:
        return self._widget
    
    @property
    def sig(self) -> SignalInstance:
        return self._sig
    
    def eventFilter(self, obj: QWidget, event: QEvent):
        match (event.type()):
            case QEvent.FocusOut:
                # print("Lost focus!\nReason: {}".format(event.reason()))
                # if event.reason() == Qt.FocusReason.ActiveWindowFocusReason:
                #     return True

                # self.sig.emit(self.widget)
                return True
            case QEvent.FocusIn:
                # print("Gained focus!")
                return True
            case _:
                return super().eventFilter(obj, event)

class WindowEventFilter(CustomEventFilter):
    def __init__(self, widget):
        super().__init__(widget)

    @property
    def widget(self):
        return super().widget
    
    def eventFilter(self, obj: QWidget, event:QEvent):
        match (event.type()):
            case QEvent.MouseButtonRelease:
                #TODO
                print("mouse window!")
                sub: SubBox = obj.findChild(SubBox)

                evFilter: SubBoxEventFilter = sub.findChild(SubBoxEventFilter)
                return evFilter.eventFilter(sub, event)

                # return sub.eventFilter(sub, event)  # this doesn't work.
            case _:
                return super().eventFilter(obj, event)

class SubBoxEventFilter(CustomEventFilter): 
    """blah blah blah
    """
    def __init__(self, widget: QWidget):
        super().__init__(widget)

    @property
    def widget(self):
        return super().widget

    # Actual eventFilter function. Obj will be the widget this filterObj is installed on,
    # Event is a subclass of QEvent and can be accessed through its enum: 
    # QEvent.Resize is similar to QResizeEvent
    def eventFilter(self, obj: QObject, event:QEvent):
        # print(type(obj))
        match (event.type()):
            case QEvent.Resize:   # TODO
                # Won't matter for final product(I think?) but for test purposes will be implemented here
                
                return True
            
            case QEvent.Move:
                # Check meatball
                print("Sub moving meatball!")
                if obj.findChild(TestSongMeatball):
                    meatball: TestSongMeatball = obj.findChild(TestSongMeatball)
                    meatball.findPos()
                    return True
                
                # Return True to notify app that moving took place.
                return True
            
            case _:
                # For all events other than move and resize, handle according to QObject built-in eventFilter().
                return super().eventFilter(obj, event)

mre.py,没有事件过滤器

import sys

from PySide6.QtCore import (Qt, QSize, QPoint, QRect,
                            QEvent, QObject,
                            Signal, SignalInstance, Slot,
                            )

from PySide6.QtGui import (QResizeEvent, QMoveEvent,
                           QFocusEvent, )

from PySide6.QtWidgets import (QWidget, QPushButton, QLabel,
                               QHBoxLayout, QVBoxLayout, 
                               QMainWindow, QApplication,
                               QSizePolicy, QLayout, QLayoutItem
                               )

import EvFilter

class TestSong(QWidget):

    # Create signals to relay info about meatball
    meatballCreated = Signal(QWidget, name="meatballCreated")
    meatballDestroyed = Signal(QWidget, name="meatballDestroyed")

    def __init__(self):
        super().__init__()

        self.setStyleSheet("background-color: blue")

        # Init layout on widget
        layout = QHBoxLayout(self)

        # Crate widgets
        label = QLabel("Label")
        meatball = TestSongButton("Meatball button")

        layout.addWidget(label)
        layout.addWidget(meatball)

        # connect clicked signal to relay into a meatballCreate signal, passing this widget
        # as a param
        meatball.clicked.connect(
            lambda checked: self.meatballCreated.emit(self))  
    
class TestSongButton(QPushButton):
    def __init__(self, text):
        super().__init__(text)

        self.setStyleSheet("background-color: purple")
    
class TestSongMeatball(QWidget):
    def __init__(self, songWidget: TestSong, parent=None):
        super().__init__(parent)

        # Set reference to song widget
        self._songWidget = songWidget

        self.setStyleSheet("background-color: red")

        # Create sizePolicy obj, init with horizontal and vertical preferences
        policy = QSizePolicy()
        policy.setHorizontalPolicy(QSizePolicy.Policy.Preferred)
        policy.setVerticalPolicy(QSizePolicy.Policy.Preferred)

        # Set policy, min and max size of the widget.
        self.setSizePolicy(policy)
        self.setMinimumSize(QSize(70, 50))
        self.setMaximumSize(QSize(160, 80))

        fPolicy = Qt.FocusPolicy(Qt.StrongFocus)
        self.setFocusPolicy(fPolicy)

        # Assign layout to widget
        layout = QVBoxLayout(self)
        
        # Add demo label for clarity
        text = QLabel("Meatball Menu")
        layout.addWidget(text)

    @property
    def songWidget(self):
        return self._songWidget

    def findPos(self):
        p = self.parent()
        # First check that there is a song meatball created as a child of monitorObj (_widget)
        if p.findChild(TestSongMeatball):
            # find song item and store its position
            item_pos = self.songWidget.pos()

            # Type hint for Python intellisense purposes
            # find button within song item and store its position
            button: TestSongButton = self.songWidget.findChild(TestSongButton)
            button_pos = button.pos()

            # since item sits inside SubBox, the meatball will have the same geometry starting point (I think?)
            # So to find the button we need to add them
            x,y = item_pos.x(), item_pos.y()
            nx,ny, = button_pos.x(), button_pos.y()

            # Add co-ordinates to get button's top left corner
            meatball_pos = QPoint(x+nx,y+ny)
            
            # Move to new position, then allow QT to find correct size, using SizePolicy.
            self.move(meatball_pos)
            self.adjustSize()

        return

    def sizeHint(self):
        return QSize(80,60)

class SubBox(QWidget):
    def __init__(self):
        super().__init__()

        self.setStyleSheet("background-color: green")

        # Create and apply layout
        layout = QVBoxLayout(self) 

    @Slot()
    def addWid(self, item: TestSong):
        if self.findChild(TestSongMeatball):
            print("Meatball already present.")
            return
        
        # Create meatball widget
        meatball = TestSongMeatball(item, self)
        evFilter = EvFilter.MeatballEventFilter(meatball, item.meatballDestroyed)

        meatball.findPos()
        meatball.show()  # show meatball
        meatball.setFocus()

        return

    @Slot()
    def remWid(self, meatball: TestSongMeatball):
        meatball.deleteLater()
        meatball = None

        return

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

        window_widget = QWidget()
        window_layout = QVBoxLayout(window_widget)

        winFilter = EvFilter.WindowEventFilter(window_widget)

        fPolicy = Qt.FocusPolicy(Qt.StrongFocus)
        self.setFocusPolicy(fPolicy)

        #TODO: put this into a function
        # Give total layout a label
        window_layout.addWidget(QLabel("Window"))
        
        # Create sub-box
        sub = SubBox()

        # Install event filter to SubBox
        subFilter = EvFilter.SubBoxEventFilter(sub)

        test_widget = TestSong()

        sub.layout().addWidget(test_widget)
        
        window_layout.addWidget(sub)
        
        test_widget.meatballCreated.connect(
            lambda item: sub.addWid(item))
        
        test_widget.meatballDestroyed.connect(
            lambda meatball : sub.remWid(meatball))
        
        # set window as central
        self.setCentralWidget(window_widget)
        
def main():
    # Create app
    app = QApplication(sys.argv)
    window = TestWindow()
    window.show()
    app.exec()

if __name__ == '__main__':
    main()
python module pyqt pyside6
1个回答
0
投票

如果您自己的代码中有“循环导入”,这意味着您可以创建第三个或第四个文件来保存您的内容。

第一

找到“圆圈”。

这很简单,因为你知道你的圈子在哪里。

import mre

import EvFilter

第二个

找到在哪里使用这些东西。在 mre.py 中:

Class SubBox(QWidget):
...

Class TestWindow(QMainWindow):
...

并且在 EvFilter.py 中:

Class WindowEventFilter(CustomEventFilter):
...

Class SubBoxEventFilter(CustomEventFilter):
...

第三

将这些类放入另一个文件中。一般来说,如果一个文件导入一个包含“main”的文件,我们就知道应该更正该文件,或者将 main 取出。

一个原则:“不要在其他文件中导入main。”

所以我们把其他文件中需要导入的东西拿出来,放到另一个文件中。

tsong.py(存储TestSong等)

from PySide6.QtCore import (Qt, QSize, QPoint, QRect,
                            QEvent, QObject,
                            Signal, SignalInstance, Slot,
                            )

from PySide6.QtGui import (QResizeEvent, QMoveEvent,
                           QFocusEvent, )

from PySide6.QtWidgets import (QWidget, QPushButton, QLabel,
                               QHBoxLayout, QVBoxLayout, 
                               QMainWindow, QApplication,
                               QSizePolicy, QLayout, QLayoutItem
                               )
class TestSong(QWidget):

    # Create signals to relay info about meatball
    meatballCreated = Signal(QWidget, name="meatballCreated")
    meatballDestroyed = Signal(QWidget, name="meatballDestroyed")

    def __init__(self):
        super().__init__()

        self.setStyleSheet("background-color: blue")

        # Init layout on widget
        layout = QHBoxLayout(self)

        # Crate widgets
        label = QLabel("Label")
        meatball = TestSongButton("Meatball button")

        layout.addWidget(label)
        layout.addWidget(meatball)

        # connect clicked signal to relay into a meatballCreate signal, passing this widget
        # as a param
        meatball.clicked.connect(
            lambda checked: self.meatballCreated.emit(self))  
    
class TestSongButton(QPushButton):
    def __init__(self, text):
        super().__init__(text)

        self.setStyleSheet("background-color: purple")
    
class TestSongMeatball(QWidget):
    def __init__(self, songWidget: TestSong, parent=None):
        super().__init__(parent)

        # Set reference to song widget
        self._songWidget = songWidget

        self.setStyleSheet("background-color: red")

        # Create sizePolicy obj, init with horizontal and vertical preferences
        policy = QSizePolicy()
        policy.setHorizontalPolicy(QSizePolicy.Policy.Preferred)
        policy.setVerticalPolicy(QSizePolicy.Policy.Preferred)

        # Set policy, min and max size of the widget.
        self.setSizePolicy(policy)
        self.setMinimumSize(QSize(70, 50))
        self.setMaximumSize(QSize(160, 80))

        fPolicy = Qt.FocusPolicy(Qt.StrongFocus)
        self.setFocusPolicy(fPolicy)

        # Assign layout to widget
        layout = QVBoxLayout(self)
        
        # Add demo label for clarity
        text = QLabel("Meatball Menu")
        layout.addWidget(text)

    @property
    def songWidget(self):
        return self._songWidget

    def findPos(self):
        p = self.parent()
        # First check that there is a song meatball created as a child of monitorObj (_widget)
        if p.findChild(TestSongMeatball):
            # find song item and store its position
            item_pos = self.songWidget.pos()

            # Type hint for Python intellisense purposes
            # find button within song item and store its position
            button: TestSongButton = self.songWidget.findChild(TestSongButton)
            button_pos = button.pos()

            # since item sits inside SubBox, the meatball will have the same geometry starting point (I think?)
            # So to find the button we need to add them
            x,y = item_pos.x(), item_pos.y()
            nx,ny, = button_pos.x(), button_pos.y()

            # Add co-ordinates to get button's top left corner
            meatball_pos = QPoint(x+nx,y+ny)
            
            # Move to new position, then allow QT to find correct size, using SizePolicy.
            self.move(meatball_pos)
            self.adjustSize()

        return

    def sizeHint(self):
        return QSize(80,60)

子盒.py


from PySide6.QtCore import (Qt, QSize, QPoint, QRect,
                            QEvent, QObject,
                            Signal, SignalInstance, Slot,
                            )

from PySide6.QtGui import (QResizeEvent, QMoveEvent,
                           QFocusEvent, )

from PySide6.QtWidgets import (QWidget, QPushButton, QLabel,
                               QHBoxLayout, QVBoxLayout, 
                               QMainWindow, QApplication,
                               QSizePolicy, QLayout, QLayoutItem
                               )

import EvFilter
from tsong import TestSongMeatball, TestSong

class SubBox(QWidget):
    def __init__(self):
        super().__init__()

        self.setStyleSheet("background-color: green")

        # Create and apply layout
        layout = QVBoxLayout(self) 

    @Slot()
    def addWid(self, item: TestSong):
        if self.findChild(TestSongMeatball):
            print("Meatball already present.")
            return
        
        # Create meatball widget
        meatball = TestSongMeatball(item, self)
        evFilter = EvFilter.MeatballEventFilter(meatball, item.meatballDestroyed)

        meatball.findPos()
        meatball.show()  # show meatball
        meatball.setFocus()

        return

    @Slot()
    def remWid(self, meatball: TestSongMeatball):
        meatball.deleteLater()
        meatball = None

        return

我们只需要在 EvFilter.py 和 main.py 中导入这些东西:

EvFilter.py

from PySide6.QtCore import (QEvent, QObject,
                            Signal, SignalInstance, 
                            )

from PySide6.QtWidgets import (QWidget, )

# from mre import (TestSongMeatball, SubBox, )
from tsong import TestSongMeatball
from subbox import SubBox

... and we don't change any below.

mre.py

import sys

from PySide6.QtCore import (Qt, QSize, QPoint, QRect,
                            QEvent, QObject,
                            Signal, SignalInstance, Slot,
                            )

from PySide6.QtGui import (QResizeEvent, QMoveEvent,
                           QFocusEvent, )

from PySide6.QtWidgets import (QWidget, QPushButton, QLabel,
                               QHBoxLayout, QVBoxLayout, 
                               QMainWindow, QApplication,
                               QSizePolicy, QLayout, QLayoutItem
                               )

import EvFilter
from subbox import SubBox
from tsong import TestSong



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

        window_widget = QWidget()
        window_layout = QVBoxLayout(window_widget)

        winFilter = EvFilter.WindowEventFilter(window_widget)

        fPolicy = Qt.FocusPolicy(Qt.StrongFocus)
        self.setFocusPolicy(fPolicy)

        #TODO: put this into a function
        # Give total layout a label
        window_layout.addWidget(QLabel("Window"))
        
        # Create sub-box
        sub = SubBox()

        # Install event filter to SubBox
        subFilter = EvFilter.SubBoxEventFilter(sub)

        test_widget = TestSong()

        sub.layout().addWidget(test_widget)
        
        window_layout.addWidget(sub)
        
        test_widget.meatballCreated.connect(
            lambda item: sub.addWid(item))
        
        test_widget.meatballDestroyed.connect(
            lambda meatball : sub.remWid(meatball))
        
        # set window as central
        self.setCentralWidget(window_widget)
        
def main():
    # Create app
    app = QApplication(sys.argv)
    window = TestWindow()
    window.show()
    app.exec()

if __name__ == '__main__':
    main()
© www.soinside.com 2019 - 2024. All rights reserved.