PyQt5 - 封装/使组件可重用 - 示例:QTimer/QLabel 在父 class 之外实现
PyQt5 - encapsulate / make a component reusable - example: QTimer/QLabel implementation outside of parent class
我在我的几个 PyQt5 应用程序中实现了一个显示当前时间的标签。这是一个 MRE:
import sys
import logging
from PyQt5 import QtWidgets, QtCore, QtGui
__log__ = logging.getLogger()
class App(QtWidgets.QApplication):
def __init__(self, sys_argv):
super(App, self).__init__(sys_argv)
self.main_view = MainView()
self.main_view.show()
class MainView(QtWidgets.QMainWindow):
def __init__(self):
super().__init__()
self.setObjectName("MreUi")
self.resize(300, 100)
self.setWindowTitle('MreUi')
self.label = QtWidgets.QLabel()
self.setCentralWidget(self.label)
config_clock(self.label)
self.start_clocks()
def start_clocks(self):
timer = QtCore.QTimer(self)
timer.timeout.connect(self.show_time)
timer.start(1000)
def show_time(self):
current_time = QtCore.QTime.currentTime()
clock_label_time = current_time.toString('hh:mm:ss')
self.label.setText(clock_label_time)
def config_clock(label):
label.setAlignment(QtCore.Qt.AlignCenter)
font = QtGui.QFont('Arial', 24, QtGui.QFont.Bold)
label.setFont(font)
if __name__ == '__main__':
logging.basicConfig()
app = App(sys.argv)
try:
sys.exit(app.exec_())
except Exception as e:
__log__.error('%s', e)
当我在我的几个 PyQt 应用程序中实现了一个类似的时钟时,我认为将它实现为一个组件/封装它会很好。首先,我想到通过从任何 QWidget 调用一个 config_clock 函数来做到这一点,并让该函数完成~所有为指定标签实现时钟的工作。这将避免在多个应用程序中重复使用 MainView 的 writing/calling start_clocks 和 show_time 实例方法。但是当我开始编写代码时...
# from inside my QWidget:
config_clock(self.label)
# this function would live outisde the class, thus reusable by diff Qt apps:
def config_clock(label):
# start the clock
# set default font, etc for label
# instantiate QtCore.QTimer
# # but that's when I realized I've always passed self to QtCore.QTimer and that maybe encapsulating this isn't as trivial as I thought.
我是否应该创建我自己的某种 ClockLabel() 对象,它被传递给 QtWidget 的标签并且也可以是每个可能需要它的 QtWidget 的实例属性?这对我来说有点笨重。但肯定有办法在 PyQt 中制作 'reusable component',我只是不知道如何...
我也不确定如果我将 MainView(QtWidgets.QMainWindow) 作为参数传递给 ClockLabel() class 我写了一个 config_clock 函数,其签名可能如下所示:
def config_clock(label, parent_qtwidget):
# also feels clunky and not sure if parent would be the right term
谢谢
对于 QtWidgets,通过继承来专门化小部件是正常的。以下是您可以如何重新排列代码以生成可重用小部件的示例:
class ClockLabel(QtWidgets.QLabel):
def __init__(self, parent=None):
super().__init__(parent)
self.setAlignment(QtCore.Qt.AlignCenter)
font = QtGui.QFont('Arial', 24, QtGui.QFont.Bold)
self.setFont(font)
self._timer = QtCore.QTimer(self)
self._timer.timeout.connect(self._show_time)
def start(self):
self._timer.start(1000)
def stop(self):
self._timer.stop()
def _show_time(self):
current_time = QtCore.QTime.currentTime()
clock_label_time = current_time.toString('hh:mm:ss')
self.setText(clock_label_time)
我在我的几个 PyQt5 应用程序中实现了一个显示当前时间的标签。这是一个 MRE:
import sys
import logging
from PyQt5 import QtWidgets, QtCore, QtGui
__log__ = logging.getLogger()
class App(QtWidgets.QApplication):
def __init__(self, sys_argv):
super(App, self).__init__(sys_argv)
self.main_view = MainView()
self.main_view.show()
class MainView(QtWidgets.QMainWindow):
def __init__(self):
super().__init__()
self.setObjectName("MreUi")
self.resize(300, 100)
self.setWindowTitle('MreUi')
self.label = QtWidgets.QLabel()
self.setCentralWidget(self.label)
config_clock(self.label)
self.start_clocks()
def start_clocks(self):
timer = QtCore.QTimer(self)
timer.timeout.connect(self.show_time)
timer.start(1000)
def show_time(self):
current_time = QtCore.QTime.currentTime()
clock_label_time = current_time.toString('hh:mm:ss')
self.label.setText(clock_label_time)
def config_clock(label):
label.setAlignment(QtCore.Qt.AlignCenter)
font = QtGui.QFont('Arial', 24, QtGui.QFont.Bold)
label.setFont(font)
if __name__ == '__main__':
logging.basicConfig()
app = App(sys.argv)
try:
sys.exit(app.exec_())
except Exception as e:
__log__.error('%s', e)
当我在我的几个 PyQt 应用程序中实现了一个类似的时钟时,我认为将它实现为一个组件/封装它会很好。首先,我想到通过从任何 QWidget 调用一个 config_clock 函数来做到这一点,并让该函数完成~所有为指定标签实现时钟的工作。这将避免在多个应用程序中重复使用 MainView 的 writing/calling start_clocks 和 show_time 实例方法。但是当我开始编写代码时...
# from inside my QWidget:
config_clock(self.label)
# this function would live outisde the class, thus reusable by diff Qt apps:
def config_clock(label):
# start the clock
# set default font, etc for label
# instantiate QtCore.QTimer
# # but that's when I realized I've always passed self to QtCore.QTimer and that maybe encapsulating this isn't as trivial as I thought.
我是否应该创建我自己的某种 ClockLabel() 对象,它被传递给 QtWidget 的标签并且也可以是每个可能需要它的 QtWidget 的实例属性?这对我来说有点笨重。但肯定有办法在 PyQt 中制作 'reusable component',我只是不知道如何...
我也不确定如果我将 MainView(QtWidgets.QMainWindow) 作为参数传递给 ClockLabel() class 我写了一个 config_clock 函数,其签名可能如下所示:
def config_clock(label, parent_qtwidget):
# also feels clunky and not sure if parent would be the right term
谢谢
对于 QtWidgets,通过继承来专门化小部件是正常的。以下是您可以如何重新排列代码以生成可重用小部件的示例:
class ClockLabel(QtWidgets.QLabel):
def __init__(self, parent=None):
super().__init__(parent)
self.setAlignment(QtCore.Qt.AlignCenter)
font = QtGui.QFont('Arial', 24, QtGui.QFont.Bold)
self.setFont(font)
self._timer = QtCore.QTimer(self)
self._timer.timeout.connect(self._show_time)
def start(self):
self._timer.start(1000)
def stop(self):
self._timer.stop()
def _show_time(self):
current_time = QtCore.QTime.currentTime()
clock_label_time = current_time.toString('hh:mm:ss')
self.setText(clock_label_time)