当您使用 Qt_Designer 或 Qt_Creator 设计表单时,任何给定小部件的 objectName 始终设置为某个值。但是,如果您在代码中创建一个小部件并且稍后需要 objectName,则必须显式分配它。那么小部件分配至少需要两行代码。这看起来很不优雅。
示例:
button1 = QPushButton('button caption') # at this point objectName is some kind of empty string
button1.setObjectName('button1')
如果您稍后需要查找小部件(即使用 findChild),则必须设置 objectName,否则您就不走运了。
是否有某种方法可以自动设置 objectName 而无需额外的代码行?我查看了PyQt5参考指南并没有找到这样的功能。在代码审查中提出了类似的问题,但没有得到答案。两行代码并不是世界末日,但它似乎是多余的。不知何故,我需要为 Python(第一行)分配该名称两次,为 Qt 分配一次。
您可以在创建按钮时将
objectName
作为关键字参数传递。
button1 = QPushButton('button caption', objectName='button1')
这可以在初始化期间将其扩展到任何 Qt 属性:
button1 = QPushButton(text='button caption', objectName='button1', icon=icon1)
此外,构建对象时也可以连接信号:
button1 = QPushButton(text='button caption', objectName='button1', clicked=someMethod)
添加的命名参数相当于
button1.clicked.connect(someMethod)
import uuid
# Decorator for automatically setting object name as class name + UUID
def set_unique_name(class_type):
original_init = class_type.__init__
def new_init(self, *args, **kwargs):
auto_set_name = kwargs.pop('auto_set_name', True) # Get the auto_set_name parameter from kwargs, default to True
original_init(self, *args, **kwargs)
if auto_set_name:
class_name = self.__class__.__name__ # Get the class name
unique_name = f"{class_name}_{str(uuid.uuid4())}" # Class name + UUID
self.setObjectName(unique_name)
class_type.__init__ = new_init
return class_type
# Use the decorator to set object names
@set_unique_name
class MyWidget(QWidget):
pass
@set_unique_name
class MyButton(QPushButton):
pass
@set_unique_name
class MyGroupBox(QGroupBox):
pass
# Example usage
if __name__ == "__main__":
from PyQt5.QtWidgets import QApplication, QVBoxLayout, QPushButton, QGroupBox
app = QApplication([])
window = QWidget()
layout = QVBoxLayout(window)
widget = MyWidget(window)
button_with_name = MyButton(window, auto_set_name=True) # Automatically set object name
button_without_name = MyButton(window, auto_set_name=False) # Do not automatically set object name
group = MyGroupBox(window)
layout.addWidget(widget)
layout.addWidget(button_with_name)
layout.addWidget(button_without_name)
layout.addWidget(group)
window.show()
app.exec_()