我是一个pyside6学习者。我正在尝试创建一个时钟基于pyside6,我想改变它的字体颜色点击。我怎样才能让它工作?
下面的代码是这个项目的一部分。
class Clock(QWidget):
def __init__(self, parent=None) -> None:
super().__init__(parent)
self.left = 1100
self.top = 800
self.width = 320
self.height = 60
# Menu
self.setContextMenuPolicy(Qt.CustomContextMenu)
self.customContextMenuRequested.connect(self.mouseRightMenu)
# Font
self.font_color = 'blue'
# UI
self.initUI()
def changeFontColor(self, fcolor) -> None:
self.font_color = fcolor
def mouseRightMenu(self, pos) -> None:
self.menu = QMenu(self)
# font color
fontColorMenu = self.menu.addMenu('font color')
self.actionB1 = QAction('black', self)
self.actionB2 = QAction('red', self)
self.actionB3 = QAction('yellow', self)
self.actionB1.triggered.connect(self.changeFontColor('black'))
def initUI(self) -> None:
# geometry of main window
self.setGeometry(self.left, self.top, self.width, self.height)
# label object
self.label = QLabel()
self.label.setAlignment(Qt.AlignCenter)
self.label.setFont(font)
self.label.setStyleSheet(f'color:{self.font_color};')
if __name__ == '__main__':
App = QApplication(sys.argv)
clock = Clock()
clock.show() # show all the widgets
App.exit(App.exec()) # start the app
目前changeFontColor
函数不工作,我不知道我在这里错过了什么
你忽略了两个基本方面。
首先,self.font_color
只是一个变量(确切地说,是一个属性)。
您明确在initUi()
和self.label.setStyleSheet()
中使用它,但这并没有"神奇地"使用它。
你所做的永远不会成功,这里有一个基本的解释:
color = 'blue'
styleSheet = f'color: {color}'
print(styleSheet)
color = 'green'
print(styleSheet)
如果你考虑以上,两个print语句将返回相同的值:改变color
不会改变styleSheet
。
这主要是因为字符串是不可变类型(因此,styleSheet
永远不会受到color
的任何更改的影响),但也因为color
和styleSheet
之间没有动态关系。
真正改变小部件方面的是对setStyleSheet()
的显式调用,更改用于前一个调用的字符串内容是完全无用的。你再次调用setStyleSheet()
来应用它。
然后,你又犯了另一个错误:信号连接使用可调用对象,但是你显式地调用changeFontColor()
函数。
考虑一下:
def myFunction(arg):
print(f'arg is "{arg}"')
return arg
# this is a call (note the parentheses), which will *execute* the function
>>> myFunction('hello')
# and will show the follwing:
arg is "hello"
# while the following will show a different result:
>>> print(myFunction('hello'))
arg is "hello"
hello
# this is a reference, which will do nothing
>>> myFunction
<function __main__.myFunction>
# notice tht difference with the above:
>>> print(myFunction)
<function myFunction at 0xZZZZZZZZ>
使用self.someObject.someSignal.connect(someFunction())
是错误的,(除非someFunction
返回对另一个函数的引用)。你直接调用你的函数(它不返回一个可调用对象),这实际上会提示一个错误。您可能没有注意到(ide通常无法显示所有输出和完整的跟踪,并且大多数Qt错误不是致命的),但是如果您在终端或提示符中运行您的程序,您可能会看到一个错误,说发生了TypeError
,因为您正在尝试连接到NoneType
。
你需要做的是:
def changeFontColor(self, fcolor) -> None:
# explicitly call setStyleSheet() with the color name
self.label.setStyleSheet(f'color: {fcolor};')
def mouseRightMenu(self, pos) -> None:
# ...
self.actionB1.triggered.connect(lambda:
self.changeFontColor('black'))
lambda
创建一个函数引用,但不调用它:当triggered
信号发出时,函数将最终被调用。
以上内容与以下内容类似:
def changeFontColor(self) -> None:
self.label.setStyleSheet('color: black')
def mouseRightMenu(self, pos) -> None:
# ...
self.actionB1.triggered.connect(self.changeFontColor)
不同的是,我们直接调用函数,它内部使用一个静态值('black'
)。
我强烈建议你对对象引用、可调用对象和对象类型做一些研究。