简体   繁体   English

如何在pyqt GUI编程中组织类

[英]How to organize classes in pyqt GUI programming

I have constructed a main window GUI using qt designer and pyqt. 我使用qt designer和pyqt构建了一个主窗口GUI。 As the program grows more complex, using only one class may result in too many methods and attributes to manage. 随着程序变得越来越复杂,仅使用一个类可能导致需要管理的方法和属性太多。 I figured that I should construct new classes in order to make things more manageable. 我认为我应该构建新的类,以使事情更易于管理。

My first question is, how do I know when do I add a new class for my application? 我的第一个问题是,我如何知道何时为我的应用程序添加新类? Is there any rule of thumb as a general guide? 是否有任何经验法则作为一般指导? Is it a good idea to add a new class for new windows/tabs? 为新窗口/标签添加新类是一个好主意吗?

My second question is, if I added new classes for my application, how do my new class gain access to the Ui_MainWindow design file that I designed in Qt designer? 我的第二个问题是,如果我为我的应用程序添加了新类,我的新类如何获得我在Qt设计器中设计的Ui_MainWindow设计文件的访问权限? Below is the sample code for my main window. 下面是我的主窗口的示例代码。 Its a simple clock which displays the current time. 它是一个显示当前时间的简单时钟。 Lets say if I would like to create a class for the clock display itself, how can I rewrite the code using OOP efficiently? 让我们说如果我想为时钟显示本身创建一个类,我怎样才能有效地使用OOP重写代码?

from PyQt4 import QtGui
from myMainWindowUI import Ui_MainWindow

class MyMainWindow(QtGui.QMainWindow, Ui_MainWindow):
    def __init__(self, *args, **kwargs):
        super(MyMainWindow, self).__init__(*args, **kwargs)
        self.setupUi(self)

        self.timer = QtCore.QTimer(self)
        self.timer.timeout.connect(self.Time)
        self.timer.timeout.connect(self.Date)
        self.timer.start(1000)
        self.lcdNumber_time.setDigitCount(8)
        self.lcdNumber_time.display(strftime("%H"+":"+"%M"+":"+"%S"))
        self.label_dynamic_date.setText(strftime("%Y"+" "+"%B"+" "+"%d"+", "+"%A"))

def Time(self):
    self.lcdNumber_time.display(strftime("%H"+":"+"%M"+":"+"%S"))
def Date(self):
    self.label_dynamic_date.setText(strftime("%Y"+" "+"%B"+" "+"%d"+", "+"%A"))

app = QtGui.QApplication(sys.argv)  # A new instance of QApplication
form = MyMainWindow()                 
form.show()                         
app.exec_()

In general, this isn't necessarily a Qt-specific problem. 通常,这不一定是Qt特定的问题。 It isn't necessarily a python-specific problem either. 它也不一定是特定于python的问题。 You could extend this question to any language that supports class-based programming, or even any language with functions. 您可以将此问题扩展到支持基于类的编程的任何语言,甚至任何具有函数的语言。

It makes sense to write a class when you want to encapsulate behavior. 在想要封装行为时编写类是有意义的。 A class should usually provide a single purpose, and expose an interface to the outside that allows users of the class to interact with exactly the behavior you have designed. 类通常应该提供单一目的,并向外部公开接口,允许类的用户与您设计的行为完全交互。 Once you have this single-purpose class, you now have reusable behavior. 一旦拥有了这个单一用途的类,您现在就拥有了可重用的行为。 You could apply part of this reasoning to functions, where you say a given function has a specific purpose and once you design it to do the one bit of behavior, you now have a reusable function. 您可以将此推理的一部分应用于函数,其中您说某个给定函数具有特定目的,并且一旦您将其设计为执行一点行为,您现在就具有可重用函数。

Applying this to Qt, it would make sense to move code into its own class when its logic is no longer trivial. 将此应用于Qt,当逻辑不再是微不足道时,将代码移动到自己的类中是有意义的。 An example would be where you are first creating and showing a QMessageBox from your main window. 例如,您首先在主窗口中创建和显示QMessageBox But then at some point you need to collect more types of information, and even pass some initial information in when you construct the dialog. 但是在某些时候,您需要收集更多类型的信息,甚至在构建对话框时传递一些初始信息。 While you could construct this on the fly in your main window, as needed, it would be better to move it into its own dialog class, with its own private logic of how to be constructed. 虽然您可以根据需要在主窗口中动态构建它,但最好将其移动到自己的对话框类中,并使用自己的私有逻辑来构造。 Then you just instantiate one as needed, passing it the expected parameters to its constructor. 然后根据需要实例化一个,将预期的参数传递给它的构造函数。 Now your main window no longer has to also be concerned with constructing special dialogs. 现在,您的主窗口不再需要关注构建特殊对话框。

Another point (which wasn't exactly clear from your question) is that Qt Designer UI files each represent a single class. 另一点(你的问题并不完全清楚)是Qt Designer UI文件每个代表一个类。 It is expected that this UI definition will be applied to a single class in code. 预计此UI定义将应用于代码中的单个类。 It would be bad design to have ClassA(UI_mainWindow) and ClassB , and have ClassB access members of ClassA or know anything about the internal implementation of ClassA . 这将是糟糕的设计有ClassA(UI_mainWindow)ClassB ,并有ClassB访问成员ClassA或了解内部实现的事情ClassA Back to our topic of " separation of concerns ", ClassB should have its own purpose and interface, and be used by the ClassA(UI_mainWindow) to achieve that purpose. 回到我们关于“ 关注点分离 ”的主题, ClassB应该有自己的目的和接口,并由ClassA(UI_mainWindow)用来实现这个目的。 You don't want ClassB knowing anything about the main window or being able to do more than its designed purpose. 你不希望ClassB知道关于主窗口的任何信息,或者能够做到超出其设计目的。

Let's assume your timer example was actually more trivial than you have shown it to be. 让我们假设您的计时器示例实际上比您所示的更为简单。 If you moved it to another class, you should rely on custom signals to communicate intentions back to other classes like the main window. 如果您将其移动到另一个类,您应该依靠自定义信号将意图传达回其他类,如主窗口。 Or you could move each of the lcd and label widgets into their own custom classes with their own timer logic that made them self contained. 或者你可以将每个lcd和label小部件移动到他们自己的自定义类中,并使用自己的定时器逻辑使它们自包含。 Either way, signal/slot lets custom widgets connect with each other without needing to know anything about the other widgets. 无论哪种方式,信号/插槽都可以让自定义小部件相互连接,而无需了解其他小部件。

In summary, you could say that it would be good to create individual classes in Qt when you are constructing any non-trivial UI elements in another class (when it requires many lines of code, or it requires a bunch of SLOT functions and wiring for internal logic). 总之,你可以说当你在另一个类中构造任何非平凡的UI元素时,在Qt中创建单独的类会很好(当它需要多行代码时,或者它需要一堆SLOT函数和布线时内部逻辑)。 This will keep you from repeating your logic, and allow you to have reusable code. 这将使您不再重复逻辑,并允许您拥有可重用的代码。 It will also keep your main window smaller and easier to debug, since you can keep a smaller mental model in your brain of what the main window is doing. 它还可以使您的主窗口更小,更容易调试,因为您可以在主窗口保持较小的心理模型。 If you try to keep your UI elements as single-purpose focused and generic as possible, you will end up having a lot of classes that can be reused. 如果您尝试将UI元素保持为单一用途并且尽可能通用,那么最终会有很多可以重用的类。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM