PyQt 代码分割 - 设计与功能

2 投票
1 回答
2089 浏览
提问于 2025-04-18 06:59

我在理解如何在(PY)Qt中拆分代码方面遇到了一些困难。我的目标是把设计和导航标签放在QMainWindow中,每个标签都能触发其他文件中的代码。目前,它只能在同一个文档中的ActionClass里运行,如果把代码放到外部文档,就会出现“app未定义”的错误,当我点击标签时就会出问题。下面的代码虽然没有错误,但感觉很笨重。

class Main(QMainWindow):
    def __init__(self):
        QMainWindow.__init__(self)

        self.u = Ui_MainWindow()
        self.u.setupUi(self)

        self.u.tabs.currentChanged.connect(self.TabsChanged)

    def TabsChanged(self, i):
        if i == self.u.tabs.indexOf(self.u.tabFirst): ActionClass.__init__


class ActionClass(Main):
    def __init__(self):
        app.u.lineEdit.setText("test")

app = Main()
app.show()
sys.exit(app.exec_())

我看到的例子都是把所有代码放在一个文档里。有没有其他方法,比如把ActionClass放在另一个文件里,或者用u.lineEdit.setText而不是app.u.lineEdit.setText?看起来在ActionClass的文档中无法访问Main的继承和实例,所以我不明白它们是如何与Main进行沟通的。

非常感谢!

1 个回答

1

正如 @M4rtini 所建议的,你可以把你的代码分成几个 python模块。然后在你的主模块中导入(使用)这些模块。

比如,你发的代码可以分成几个文件:

# actions_class.py

class ActionClass(Main):
    def __init__(self):
        app.u.lineEdit.setText("test")

还有

# main.py

from action_class import ActionClass  # This line no need much explanation ;)

class Main(QMainWindow):
    def __init__(self):
        QMainWindow.__init__(self)

        self.u = Ui_MainWindow()
        self.u.setupUi(self)

        self.u.tabs.currentChanged.connect(self.TabsChanged)

    def TabsChanged(self, i):
        if i == self.u.tabs.indexOf(self.u.tabFirst): ActionClass.__init__

app = Main()
app.show()
sys.exit(app.exec_())

想要理解导入是怎么工作的,可以看看我上面给你的链接。

更多解释

我们来看看:

__init__ 方法中执行代码的正确方式是创建一个实例。下面是一个例子。

class A:
    def __init__(self):
        print("Executing A.__init__")

print("Doing things wrong")
A.__init__     # This don't print enything
print("Doing things well")
A()            # This works as expected.

所以,你的代码行应该是:

if i == self.u.tabs.indexOf(self.u.tabFirst): ActionClass.__init__

而应该改成:

if i == self.u.tabs.indexOf(self.u.tabFirst): ActionClass()

另一方面,把不是用来初始化实例的代码放在 __init__ 方法里是个坏习惯。如果你不需要实例,但又想把函数放在一个类里面(有点像 C++ 的命名空间),你可以使用 @staticmethod 装饰器。

class A:

    @staticmethod
    def foo():
        print("Oh, wow, a static method in Python!")

A.foo()

所以,你的 ActionClass 可以改写成:

class ActionClass(Main):

    @staticmethod
    def do_action:
        app.u.lineEdit.setText("test")

然后你可以这样使用它:

 if i == self.u.tabs.indexOf(self.u.tabFirst): ActionClass.do_action()

撰写回答