Метка переключателя по центру по горизонтали

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

В этой части кода я просматриваю список имен вкладок и генерирую переключатели для каждой:

def _init_vertical_tabs(self, layout, row):
    """Initialize vertical tabs"""
    tabs_widget = QtWidgets.QWidget()
    tabs_widget.setObjectName("tabs")
    vertical_tabs_layout = QtWidgets.QVBoxLayout()
    vertical_tabs_layout.setSpacing(0)
    vertical_tabs_layout.setContentsMargins(0, 0, 0, 0)
    vertical_tabs_layout.setAlignment(QtCore.Qt.AlignCenter)
    tabs_widget.setLayout(vertical_tabs_layout)
    layout.addWidget(tabs_widget, row, 0, len(self.tabs), 1)

    tabs_widget.setMinimumHeight(self.parent_height)
    tabs_widget.setMinimumWidth(self.parent_width*0.15)
    tabs_widget.setMaximumHeight(self.parent_height)
    tabs_widget.setMaximumWidth(self.parent_width*0.15)

    tab_to_widget = dict()
    for tab in self.tabs:
        tab_button = self._create_tab(tab, vertical_tabs_layout, self.parent_width*0.15, self.parent_height/len(self.tabs),)
        tab_to_widget[tab] = tab_button

def _create_tab(self, tab, layout, width, height):
    """Basic method to create a fake tab"""
    button = QtWidgets.QRadioButton(tab)
    button.setContentsMargins(0, 0, 0, 0)
    l = lambda tab_name = tab: self.toggle_visibility_tabs(tab_name)
    button.clicked.connect(l)

    button.setMinimumHeight(height)
    button.setMinimumWidth(width)
    button.setMaximumHeight(height)
    button.setMaximumWidth(width)

    layout.addWidget(button)

Затем я применил CSS:

    QWidget#tabs{
  color: #ffffff;
  background-color: #005073;
  border: 0px solid #e54d42;
  text-align: center;
}

QWidget#tabs QRadioButton{
  color: #ffffff;
  font-weight: 400;
  font-size: 20pt;
  border-radius: 0px;
  background-color: #003850; /*QLinearGradient(x1:0, y1:0, x2:0, y2:1, stop:0 #003850, stop:0.5 #005073, stop:1 #003850);*/
  margin: 0px;
  font-family: Arial, Helvetica, sans-serif;
  text-align: center;
}

QWidget#tabs QRadioButton#Validator{
  border-bottom-left-radius: 60px;
  border-left: none;
}

QWidget#tabs QRadioButton::indicator{
  width: 0px;
  height: 0px;
  border-radius: 0px;
  border: 1px solid #e54d42;
  border-top: none;
  border-right: none;
  border-left: none;
  font-family: Arial, Helvetica, sans-serif;
  text-align: center;
}

QWidget#tabs QRadioButton:hover, QWidget#tabs QRadioButton:selected,  QWidget#tabs QRadioButton:checked{
  border-left: 30px solid #e54d42;
  color: #e54d42;
}

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

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

Но это не совсем то, что я хотел, во-первых, метки переключателей по-прежнему выровнены по левому краю, а поскольку радио короче, красная рамка выбранных явно больше не слева. Может ли кто-нибудь сказать мне, есть ли простой способ добиться этого либо в коде css, либо в коде python? Я тоже пробовал text-align, но тоже не сработало.

Спасибо!


person dd95    schedule 29.03.2020    source источник
comment
Мммм. Я сомневаюсь, что это можно сделать только с таблицей стилей. Частичным решением было бы использование таблиц стилей, как будто их нет, но без установки текста, который будет закрашиваться переопределением paintEvent().   -  person musicamante    schedule 29.03.2020
comment
Привет, спасибо за ответ. Что вы подразумеваете под Частичным решением было бы использование таблиц стилей, как будто их нет, но без установки текста я не уверен в этой части. Спасибо!   -  person dd95    schedule 29.03.2020


Ответы (1)


Использование только таблиц стилей для этого практически невозможно. Я бы посоветовал вам смешать таблицы стилей и пользовательское рисование.

Прежде всего, отредактируйте таблицу стилей, установив для всех цветов переключателей значение transparent.

Затем создайте подкласс QRadioButton, который одновременно отрисовывает кнопку, вызывая реализацию базового класса и отрисовывает текст с указанным цветом и шрифтом.

class CustomRadio(QtWidgets.QRadioButton):
    def paintEvent(self, event):
        # draw the widget as paintEvent normally does
        super().paintEvent(event)

        # create a new painter on the widget
        qp = QtGui.QPainter(self)
        # create a styleoption and init it with the button
        opt = QtWidgets.QStyleOptionButton()
        self.initStyleOption(opt)

        # now we can know if the widget is hovered and/or checked
        if opt.state & (QtWidgets.QStyle.State_MouseOver | QtWidgets.QStyle.State_On):
            # if it is, set the color accordingly
            qp.setPen(QtGui.QColor('#e54d42'))
        else:
            qp.setPen(QtCore.Qt.white)
        # finally, draw the text
        qp.drawText(self.rect(), 
            QtCore.Qt.AlignCenter | QtCore.Qt.TextShowMnemonic, self.text())

Если вы используете Designer, вам нужно продвигать счетчики:

  • выберите все переключатели, щелкните правой кнопкой мыши по любому из них и выберите Promote to... в контекстном меню;
  • убедитесь, что в поле со списком «Имя базового класса» установлено значение «QRadioButton»;
  • в «Promoted class name» напишите «CustomRadio» (название подкласса выше);
  • в поле «Заголовочный файл» напишите имя файла, в котором вы сохранили подкласс, без расширения (например, если вы используете main.py, напишите «основной»); помните, что путь указан относительно файла ui (или файла py, если вы используете pyuic), поэтому, если ui/py находится в основной папке вашей программы, файл подкласса находится в каталоге «подклассы». и называется «myradios.py», вам нужно будет написать там «subclasses.myradios»;
  • нажмите «Добавить», чтобы создать новый продвигаемый класс, а затем «Продвигать», чтобы фактически продвигать выбранные радиостанции;
  • если вы раньше не выбрали все радиостанции, теперь вы можете продвигать их с помощью нового пункта «Пользовательское радио» в подменю Promote to контекстного меню;

Сохраните файл ui, создайте новый файл python, если вы используете pyuic, и все готово.

person musicamante    schedule 29.03.2020
comment
Спасибо! Я попробую, как только у меня будет возможность, и дам вам знать, как это происходит! Я ценю :) - person dd95; 30.03.2020