如何旋转QPushButton?
我想用Python和Qt4来旋转一个QPushButton(或者至少是它的文字),让它可以竖着放。我在网上看到过一些相关的文档,但我看得一头雾水——因为那些是C语言的,我对C语言不太懂。
根据我所读到的内容,似乎需要重新实现paintEvent()这个处理函数,创建一个QPainter对象并进行旋转。不过,我搞不清楚的是,怎么只针对我需要的那个QString或QPushButton来做这件事。我原以为QPaintEvent会有一个“发送者”属性,就像信号那样,但实际上没有。我从这个事件中只能得到一个QRect或QRegion。
我该如何找到与我的按钮或它的标签相关的事件呢?
或者说,真正的问题是,怎么旋转一个QPushButton?
Mru在下面建议了一些C++的例子,这个例子是完全重新实现了QPushButton。由于我对C++一窍不通,而且我并不需要完整的重新实现,我尝试根据那个例子在Python中重新实现painEvent()
处理函数。
这是我翻译的内容,但它并不工作 :\
#!/usr/bin/env python
from PyQt4 import QtGui, QtCore
import sys
class RotatedButton(QtGui.QPushButton):
def __init__(self, text, parent, orientation = "west"):
QtGui.QPushButton.__init__(self, text, parent)
self.orientation = orientation
def paintEvent(self, event):
painter = QtGui.QStylePainter(self)
if self.orientation == 'west':
painter.rotate(90)
elif self.orientation == 'east':
painter.rotate(270)
else:
raise TypeError
painter.drawControl(QtGui.QStyle.CE_PushButton, self.getSyleOptions())
def getSyleOptions(self):
options = QtGui.QStyleOptionButton()
options.initFrom(self)
size = options.rect.size()
size.transpose()
options.rect.setSize(size)
options.features = QtGui.QStyleOptionButton.None
options.text = self.text()
options.icon = self.icon()
options.iconSize = self.iconSize()
return options
class Main(QtGui.QFrame):
def __init__(self):
QtGui.QFrame.__init__(self)
self.count = 0
self.application = QtCore.QCoreApplication.instance()
self.layout = QtGui.QHBoxLayout()
self.button = RotatedButton("Hello", self, orientation="west")
self.layout.addWidget(self.button)
self.setLayout(self.layout)
if __name__ == '__main__':
application = QtGui.QApplication(sys.argv)
application.main = Main()
application.main.show()
sys.exit(application.exec_())
3 个回答
2
我知道这条信息比原帖晚了几年,但如果你只是想让文字竖着显示而不是横着,这个方法是有效的。你可以使用QTextDocument和一些HTML代码。在每个字母后面加上
<br>
。
QTextDocument doc;
doc.setHtml("<p align=center><font>B<br>u<br>t<br>t<br>o<br>n</font></p>");
doc.setTextWidth(doc.size().width());
QPixmap pixmap(doc.size().width(), doc.size().height());
pixmap.fill( Qt::transparent );
QPainter painter(&pixmap);
doc.drawContents(&painter);
QPushButton button;
button->setIconSize(pixmap.size());
button->setIcon(pixmap);
2
如果你想让这段代码同时适用于“东”和“西”这两个方向的参数,你应该使用下面的代码:
#!/usr/bin/env python
from PyQt4 import QtGui, QtCore
import sys
class RotatedButton(QtGui.QPushButton):
def __init__(self, text, parent, orientation = "west"):
super(RotatedButton,self).__init__(text, parent)
self.orientation = orientation
def paintEvent(self, event):
painter = QtGui.QStylePainter(self)
if self.orientation == "east":
painter.rotate(270)
painter.translate(-1 * self.height(), 0);
if self.orientation == "west":
painter.rotate(90)
painter.translate(0, -1 * self.width());
painter.drawControl(QtGui.QStyle.CE_PushButton, self.getSyleOptions())
def minimumSizeHint(self):
size = super(RotatedButton, self).minimumSizeHint()
size.transpose()
return size
def sizeHint(self):
size = super(RotatedButton, self).sizeHint()
size.transpose()
return size
def getSyleOptions(self):
options = QtGui.QStyleOptionButton()
options.initFrom(self)
size = options.rect.size()
size.transpose()
options.rect.setSize(size)
options.features = QtGui.QStyleOptionButton.None
if self.isFlat():
options.features |= QtGui.QStyleOptionButton.Flat
if self.menu():
options.features |= QtGui.QStyleOptionButton.HasMenu
if self.autoDefault() or self.isDefault():
options.features |= QtGui.QStyleOptionButton.AutoDefaultButton
if self.isDefault():
options.features |= QtGui.QStyleOptionButton.DefaultButton
if self.isDown() or (self.menu() and self.menu().isVisible()):
options.state |= QtGui.QStyle.State_Sunken
if self.isChecked():
options.state |= QtGui.QStyle.State_On
if not self.isFlat() and not self.isDown():
options.state |= QtGui.QStyle.State_Raised
options.text = self.text()
options.icon = self.icon()
options.iconSize = self.iconSize()
return options
class Main(QtGui.QFrame):
def __init__(self):
QtGui.QFrame.__init__(self)
self.application = QtCore.QCoreApplication.instance()
self.layout = QtGui.QHBoxLayout()
self.button = RotatedButton("Hello", self, orientation="west")
self.layout.addWidget(self.button)
self.setLayout(self.layout)
if __name__ == '__main__':
application = QtGui.QApplication(sys.argv)
application.main = Main()
application.main.show()
sys.exit(application.exec_())
8
根据你的代码:
#!/usr/bin/env python
from PyQt4 import QtGui, QtCore
import sys
class RotatedButton(QtGui.QPushButton):
def __init__(self, text, parent, orientation = "west"):
super(RotatedButton,self).__init__(text, parent)
self.orientation = orientation
def paintEvent(self, event):
painter = QtGui.QStylePainter(self)
painter.rotate(90)
painter.translate(0, -1 * self.width());
painter.drawControl(QtGui.QStyle.CE_PushButton, self.getSyleOptions())
def minimumSizeHint(self):
size = super(RotatedButton, self).minimumSizeHint()
size.transpose()
return size
def sizeHint(self):
size = super(RotatedButton, self).sizeHint()
size.transpose()
return size
def getSyleOptions(self):
options = QtGui.QStyleOptionButton()
options.initFrom(self)
size = options.rect.size()
size.transpose()
options.rect.setSize(size)
options.features = QtGui.QStyleOptionButton.None
if self.isFlat():
options.features |= QtGui.QStyleOptionButton.Flat
if self.menu():
options.features |= QtGui.QStyleOptionButton.HasMenu
if self.autoDefault() or self.isDefault():
options.features |= QtGui.QStyleOptionButton.AutoDefaultButton
if self.isDefault():
options.features |= QtGui.QStyleOptionButton.DefaultButton
if self.isDown() or (self.menu() and self.menu().isVisible()):
options.state |= QtGui.QStyle.State_Sunken
if self.isChecked():
options.state |= QtGui.QStyle.State_On
if not self.isFlat() and not self.isDown():
options.state |= QtGui.QStyle.State_Raised
options.text = self.text()
options.icon = self.icon()
options.iconSize = self.iconSize()
return options
class Main(QtGui.QFrame):
def __init__(self):
QtGui.QFrame.__init__(self)
self.application = QtCore.QCoreApplication.instance()
self.layout = QtGui.QHBoxLayout()
self.button = RotatedButton("Hello", self, orientation="west")
self.layout.addWidget(self.button)
self.setLayout(self.layout)
if __name__ == '__main__':
application = QtGui.QApplication(sys.argv)
application.main = Main()
application.main.show()
sys.exit(application.exec_())