2011-09-07 54 views
4

我想---用Python和Qt4 ---旋轉QPushButton(或至少它的文本),以便它可以垂直站立。我見過some documentation online,但我無法理解 - 它是C語言,我是C文盲。如何旋轉QPushButton?

從我讀到的,雖然需要重新實現paintEvent()處理程序,實例化和旋轉QPainter()。然而,我無法弄清楚如何爲我需要的一個QString或QPushButton做到這一點。我認爲QPaintEvent將有一個「發送者」屬性,就像信號一樣,但它沒有。我似乎從這個事件中得到的是QRect或QRegion。

如何查找特定於我的按鈕或其標籤的事件?
或者,因爲這是真的問題,如何旋轉QPushButton?

Mru,下面這裏建議some C++ example,它完全重新實現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_()) 
+0

看一看http://www.qtcentre.org/wiki/index.php?title=OrientationButton這是C++代碼,但應該是很容易轉移到Python –

+0

@mru:好一個感謝。這是一個非常完整的文檔,它在C++中太糟糕了:) 但是我明白我應該重新實現QPushButton的painEvent()處理程序。我認爲這對我的目的已經足夠了。讓我們看看我能走多遠。 – Benjamin

+0

@mru:你明白行'QStyleOptionButton選擇; opt.initFrom(本);'? initFrom()在做什麼? – Benjamin

回答

4

#!/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_()) 
+0

它的作品謝謝:)現在有幾點我不明白。例如,爲什麼使用'size = super(RotatedButton,self).minimumSizeHint()'並再次用於'sizeHint()'?我從來不使用'super()',你是否讓按鈕佔據其祖先的大小? 'painter.translate()'翻轉按鈕,是不是很容易旋轉270°? – Benjamin

+0

超級調用父類,請參閱http://docs.python.org/library/functions.html#super sizeHint以及minimuSizeHint是AFAIK僅用於佈局的東西。 –

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_()) 
1

我知道這是幾年後的原始帖子,但這個作品,如果你只是希望文字是垂直的而不是水平的。使用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);