如何旋转 QPushButton?

发布于 2024-12-03 13:59:16 字数 2473 浏览 2 评论 0原文

我想用 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_())

I would like---with Python and Qt4---to rotate a QPushButton (or at least its text) so it can stand vertically. I've seen some documentation online, but I couldn't make much sense out of it---it's in C and I'm C-illiterate.

From what I read though, one needs to re-implement the paintEvent() handler, instantiate and rotate a QPainter(). What I can't figure out however is how to do this for the one QString or QPushButton I need only. I assumed the QPaintEvent would have a "sender" attribute, like signals do, but it hasn't. All I can seem to get from this event is a QRect or QRegion.

How can I find out the event specific to my button or its label?
Or, because that's the question really, how to rotate a QPushButton?

Mru, here below suggested some C++ example, which reimplements the QPushButton completely. Since I have no clue about C++ and since I don't really need a full reimplementation, I've tried to reimplement the painEvent() handler in Python, based on that example.

Here is what I have translated, but it does not work :\

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

北城孤痞 2024-12-10 13:59:16

根据您的代码:

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

Based on your code:

#!/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_())
青芜 2024-12-10 13:59:16

如果您希望此代码适用于“东”和“西”方向参数,您应该使用以下代码:

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

If you want this code working for both "east" and "west" orientation arguments you should use this:

#!/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_())
荒人说梦 2024-12-10 13:59:16

我知道这是在原始帖子发布几年后,但如果您只想让文本垂直而不是水平,那么这是有效的。使用 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);

I know this is a few years after the original post but this works if you just want text to be vertical instead of horizontal. Use QTextDocument and some HTML. Add

<br>

after each letter.

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);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文