PyQT: поверните QLabel так, чтобы он располагался по диагонали, а не по горизонтали.

Я работаю над приложением с сенсорным экраном, где пространство графического интерфейса очень ограничено. Я хотел бы немного повернуть QLabel, чтобы он был либо вертикальным, либо немного смещенным по диагонали. Какие-либо предложения? Я не смог найти ничего подходящего в интерфейсе QLabel.

Большое спасибо!


person Jubal    schedule 21.09.2010    source источник


Ответы (5)


QLabel этого не делает. Но вы можете легко создать свой собственный виджет, содержащий немного текста:

class MyLabel(QtGui.QWidget):
    def paintEvent(self, event):
        painter = QtGui.QPainter(self)
        painter.setPen(QtCore.Qt.black)
        painter.translate(20, 100)
        painter.rotate(-90)
        painter.drawText(0, 0, "hellos")
        painter.end()

Другой вариант — нарисовать QGraphicsView, тогда у вас есть возможность отобразить реальные виджеты (т. е. QLabel) посредством любого преобразования координат.

person Ivo    schedule 21.09.2010
comment
Привет спасибо. Знаете ли вы, как это сделать с помощью QPushButton? См. ветку: stackoverflow.com/questions/7339685/how- to-rotate-a-qpushbutton Спасибо. - person neydroydrec; 08.09.2011

Я использовал этот пост, чтобы сделать другое решение, которое, я думаю, может быть лучше. Вот:

class VerticalLabel(QLabel):

    def __init__(self, *args):
        QLabel.__init__(self, *args)

    def paintEvent(self, event):
        QLabel.paintEvent(self, event)
        painter = QPainter (self)
        painter.translate(0, self.height()-1)
        painter.rotate(-90)
        self.setGeometry(self.x(), self.y(), self.height(), self.width())
        QLabel.render(self, painter)

    def minimumSizeHint(self):
        size = QLabel.minimumSizeHint(self)
        return QSize(size.height(), size.width())

    def sizeHint(self):
        size = QLabel.sizeHint(self)
        return QSize(size.height(), size.width())
person Controlix    schedule 15.12.2014

Попробуй это

class myStyle(QCommonStyle):

    def __init__(self, angl=0, point=QPoint(0, 0)):
        super(myStyle, self).__init__()
        self.angl = angl
        self.point = point

    def drawItemText(self, painter, rect, flags, pal, enabled, text, textRole):
        if not text:
            return
        savedPen = painter.pen()
        if textRole != QPalette.NoRole:
            painter.setPen(QPen(pal.brush(textRole), savedPen.widthF()))
        if not enabled:
            pen = painter.pen()
            painter.setPen(pen)
        painter.translate(self.point)
        painter.rotate(self.angl)
        painter.drawText(rect, flags, text)
        painter.setPen(savedPen)

а также

label = QLabel()
label.setStyle(myStyle(-45, QPoint(0, 100)))
person Denis Sidorenkov    schedule 05.12.2019

Ответ от @Controlix является общей реализацией, однако я получил предупреждение о «рекурсивном вызове рисования». Я смог решить эту проблему, объединив подходы @Controlix и @Ivo. Вот моя реализация:

from PyQt5.Qt import QLabel
from PyQt5 import QtGui


class VerticalLabel(QLabel):

    def __init__(self, *args):
        QLabel.__init__(self, *args)

    def paintEvent(self, event):
        painter = QtGui.QPainter(self)
        painter.translate(0, self.height())
        painter.rotate(-90)
        painter.drawText(0, self.width()/2, self.text())
        painter.end()
person SingularRiver    schedule 24.01.2020

Я взял все вышеперечисленные посты и протестировал каждый. Я считаю, что это лучшее сочетание из всех.

Это центрирует текст по горизонтали и вертикали и правильно устанавливает подсказки по размеру.

введите здесь описание изображения

from PyQt5 import QtGui
from PyQt5 import QtWidgets
from PyQt5 import QtCore

class VerticalLabel(QtWidgets.QLabel):

    def __init__(self, *args):
        QtWidgets.QLabel.__init__(self, *args)

    def paintEvent(self, event):
        painter = QtGui.QPainter(self)
        painter.translate(0, self.height())
        painter.rotate(-90)
        # calculate the size of the font
        fm = QtGui.QFontMetrics(painter.font())
        xoffset = int(fm.boundingRect(self.text()).width()/2)
        yoffset = int(fm.boundingRect(self.text()).height()/2)
        x = int(self.width()/2) + yoffset
        y = int(self.height()/2) - xoffset
        # because we rotated the label, x affects the vertical placement, and y affects the horizontal
        painter.drawText(y, x, self.text())
        painter.end()
        
    def minimumSizeHint(self):
        size = QtWidgets.QLabel.minimumSizeHint(self)
        return QtCore.QSize(size.height(), size.width())

    def sizeHint(self):
        size = QtWidgets.QLabel.sizeHint(self)
        return QtCore.QSize(size.height(), size.width())

class Example(QtWidgets.QWidget):
    def __init__(self):
        super(Example, self).__init__()
        self.initUI()

    def initUI(self):
        lbl1 = VerticalLabel('ABSOLUTE')
        lbl1.setFont(QtGui.QFont('Arial', 20))
        lbl1.setStyleSheet("QLabel { background-color : black; color : orange; }"); 
        lbl2 = VerticalLabel('lbl 2')
        lbl3 = VerticalLabel('lbl 3')
        hBoxLayout = QtWidgets.QHBoxLayout()
        hBoxLayout.addWidget(lbl1)
        hBoxLayout.addWidget(lbl2)
        hBoxLayout.addWidget(lbl3) 
        self.setLayout(hBoxLayout)
        self.setGeometry(300, 300, 250, 150) 
        self.show()

def main():
    app = QtWidgets.QApplication(sys.argv)
    ex = Example()
    sys.exit(app.exec_())

if __name__ == '__main__':
    main()
person Ben DeMott    schedule 13.05.2021