0

my code

import sys
from PyQt5.QtWidgets import (QRadioButton, QHBoxLayout, QButtonGroup, 
    QApplication, QWidget, QLabel)
from PyQt5.QtGui import QIcon, QPixmap
from PyQt5.QtCore import QSize, Qt
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWidgets import *



class Label(QLabel):
    def __init__(self, parent=None):
        super(Label, self).__init__(parent)
        self.parent = parent
        self._animation = QtCore.QVariantAnimation(
                startValue=QtGui.QColor("blue"),
                endValue=QtGui.QColor("green"),
                valueChanged=self._on_value_changed,
                duration=400,
            )
        self.setCursor(QtGui.QCursor(QtCore.Qt.PointingHandCursor))


    def _on_value_changed(self, color):
        foreground = (
            QtGui.QColor("black")
            if self._animation.direction() == QtCore.QAbstractAnimation.Forward
            else QtGui.QColor("yellow")
        )
        self._update_stylesheet(color, foreground)

    def _update_stylesheet(self, background, foreground):
        self.setStyleSheet(
            """
        QLabel{
            padding:10;
            margin10;
            background: %s;
            color: %s;
        }
        """
            % (background.name(), foreground.name())
        )
    def enterEvent(self, event):
        self._animation.setDirection(QtCore.QAbstractAnimation.Backward)
        self._animation.start()
        super().enterEvent(event)

    def leaveEvent(self, event):
        self._animation.setDirection(QtCore.QAbstractAnimation.Forward)
        self._animation.start()
        super().leaveEvent(event)

    def mousePressEvent(self, event):
        self.parent.click()


class Radio(QRadioButton): 
    def __init__(self, parent=None):
        super(Radio, self).__init__(parent)
        lay = QtWidgets.QGridLayout(self)
        lay.setSpacing(0)
        lay.setContentsMargins(0, 0, 0, 0)
        self.setText('0')
        self.label = Label(self)
        self.label.setText('test0098908uhjhjk9')

        sizePolicy = QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.label.sizePolicy().hasHeightForWidth())


        self.setStyleSheet('QRadioButton{background:red} QRadioButton::indicator{ text:rgba(0, 0, 0, 0); background:rgba(0, 0, 0, 0)}')


        self.label.setSizePolicy(sizePolicy)

        self.label.setStyleSheet('padding:10;margin10;background:green')
        self.label.setAlignment(Qt.AlignCenter)
        lay.addWidget(self.label, 0, 0, 1, 1)

        print('radio-2 h - {}'.format(self.height()))
        print('radio-2 w - {}'.format(self.width()))
        print('label h -{}'.format(self.label.height()))
        print('label w -{}'.format(self.label.width()))

        self.setMinimumSize(QSize(140, 34))

        self.toggled.connect(self.on_off)
    def on_off(self):
        if self.isChecked():                                   
            self.label.setText('<div>&#xe3434</div>')
        else:
            self.label.setText('<div>&#xe3456</div>')


class Window(QWidget):
    def __init__(self):
        super().__init__()

        self._dictRB = {                                            
            '0': False,
            'rb1': False,
            'rb2': False,
            'rb3': False,
        }

        self.main_layout = QHBoxLayout(self)



        self.buttonGroup = QButtonGroup()
        self.attr_layout = QHBoxLayout()
        self.main_layout.addLayout(self.attr_layout)


        self.rb0 = Radio()                             #QRadioButton() # 'rb0'


        sizePolicy = QSizePolicy(QSizePolicy.Minimum, QSizePolicy.Minimum)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.rb0.sizePolicy().hasHeightForWidth())
        self.rb0.setSizePolicy(sizePolicy)





        self.attr_layout.addWidget(self.rb0)
        self.buttonGroup.addButton(self.rb0)

        self.rb1 = QRadioButton('rb1')
        self.attr_layout.addWidget(self.rb1)
        self.buttonGroup.addButton(self.rb1)               

        self.rb2 = QRadioButton('rb2')
        self.attr_layout.addWidget(self.rb2)
        self.buttonGroup.addButton(self.rb2) 

        self.rb3 = QRadioButton('rb3')                               
        self.buttonGroup.addButton(self.rb3)                         

        self.buttonGroup.buttonClicked.connect(self.check_button)

    def check_button(self, radioButton):
        if self._dictRB[radioButton.text()]:
            self._dictRB[radioButton.text()] = False
            self._dictRB['rb3'] = True
            self.rb3.setChecked(True)              
        else:
            for b in self._dictRB:
                self._dictRB[b] = False
            self._dictRB[radioButton.text()] = True

        print("Button -> `{} - {}`".format(radioButton.text(), radioButton.isChecked()))


if __name__ == '__main__':
    app = QApplication(sys.argv)
    w = Window()
    #w.setMinimumSize(QSize(0, 400))
    w.show()
    sys.exit(app.exec_())

I need Radio() not to be less than QLabel. And it behaved almost as if QLabel was connected to the Layout while inside the QWidget with the saved margin and padding.

enter image description here

I tried to use setMinimumSize() but QLabel is always 30X100 until you manually specify the size. But constantly calculating margin, padding, font-size, border, and other qss properties is too inconvenient.

It should work something like this

enter image description here

But without constant writing self.setMinimumSize(QSize (140, 34)) manual

askqest
  • 47
  • 2
  • 9
  • 1
    I'm not sure I've understood. Do you want the label to be shown "in place" of the normal "label" the radio has? – musicamante Mar 23 '20 at 23:58
  • Yes, I want to replace the entire look of the label with a radio. Because the label supports inaccessible radio functions.But the problem is that the radio ignores the geometry of the label.And I can’t use Layout and qss. I need all the content on the label to be visible. The text can be of different lengths. If the parent is larger than the label, then the label should be in the center and the background should NOT fill the entire space of the parent. If the geometry of the parent is not specified, then the parent should become as small as possible but not close the label with pad. marg. bor. – askqest Mar 24 '20 at 05:39
  • 1
    Sorry, but your explanation is not very clear. Is [this](https://i.stack.imgur.com/T6ddv.png) something like what you want to achieve? Otherwise, please clarify, and provide a mockup image of what you want to do. – musicamante Mar 24 '20 at 05:56
  • @musicamante Almost only the radio icon and the indent from it should be hidden. – askqest Mar 24 '20 at 10:48
  • 1
    "Almost"? So you practically want a QLabel that "behaves" like a radio button? I sincerely hope that's not the case, because it would make it completely unusable and then you're probably having an [XY problem](https://meta.stackexchange.com/questions/66377/what-is-the-xy-problem). If you want a radio button, it should *look* like a radio button (or at least something that "seems" checkable and clearly has a dual on/off state); if it doesn't look like a radio button, then you don't need a radio button. – musicamante Mar 24 '20 at 11:04
  • @musicamante I do not quite understand the essence of your question. I have a problem with the fact that the radio does not interact with the label geometry. I wanted to focus on this, so I cut my code. But it looks a bit confusing to you. Sorry. – askqest Mar 24 '20 at 17:32
  • @musicamante My code does the following. These are three radios with the ability to turn off. Instead of using regular circles with a dot, it uses the font icon & # xe3434 and & # xe3456. But there was a problem in that the radio is not able to convert the text into an icon and the label can do it. So I used the label inside the radio But I say it again. The problem is that the radio ignores the geometry of the label – askqest Mar 24 '20 at 17:33
  • The core of the problem was completely clear, what was *not* was the expected result and, especially, the reason for that (which you should've said from the beginning): we don't just blindly answer, if a question brings us doubts about its origin. I could give a simple answer as soon as I get to my pc, but an important question in the meantime: exactly *why* do you need to use unicode characters instead of the normal appearance? Are you aware of the *multiple* negative side effects of doing it (I can count at least 4, including lack of character support in the system font, most importantly)? – musicamante Mar 24 '20 at 18:36
  • @Well, I use my own font. which connect through QFontDatabase Before that, I used svg icons. But I ran into the problem that I can’t change the color of the icon. There was one solution, but I didn’t like it because it had a lot of code and in the future it would affect on the speed of work and also QPixmap made svg the icon is very pixelated. I would like to choose the best option to improve my code. But so far I have only two options: through a font with 4 or more problems or through svg but with a lot of code and cut graphics. – askqest Mar 25 '20 at 05:11
  • So, if I understand correctly, the source of the problem is that you want to use your own image for the radio indicator and the problem is that the methods you've tried so far result in an unsatisfacting rendering of the image? Or is there anything else, like text formatting, colors, alignment (besides the radio "character", I mean)? – musicamante Mar 25 '20 at 05:24
  • @musicamante I think yes, you are right. I want to use an icon instead of a button. if you list all the functions then All the button should do is 1) switch between the other buttons `QRadioButton`, 2) turn off when you press the button again `self._dictRB`, 3) Have your own icon `QFontDatabase` or `QPixmap`, 4) Change your icon depending on whether it is pressed or not `on_off(self)`, – askqest Mar 25 '20 at 07:25
  • @musicamante 5) Smoothly change your color when the mouse is pointing at it `self._animation`. 6) DO NOT allow layout to hide the button, taking into account properties margin, padding, font-size, border `self.setMinimumSize`. I did not notice any problems with the alignment of the icon; all of them were always aligned in the center and the background size does not change in size. I would like it to not change. What do you think of it? – askqest Mar 25 '20 at 07:26
  • Well, I think that you should really begin to ask the right questions :-P You had a similar problem in at least two of your previous posts that I remember of. Always try to describe what you *really* need, the origin of that need and the result that is expected *from that need*: this *was* an XY problem indeed. What you want to get can be easily done [through stylesheets](https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qradiobutton): create images for all states, make a basic stylesheet "template" with correct sizes and positions, and update it with the colors from the animation. – musicamante Mar 25 '20 at 09:54
  • @musicamante Sorry if I ask bad questions. I try to ask only when I have problems and I can not find the answer on the Internet. And to ask something like "Tell me how to make a magic button that knows everything and does not give errors" Somehow it's wrong. And even when someone answers a similar question, I still don’t understand how it works and if I want to change something, I can’t do it. Therefore, I try to solve the problem step by step and along the way to understand how the code works in order to ask fewer questions in the future – askqest Mar 25 '20 at 10:53
  • @musicamante About the style sheet. If I insert a picture as a background, then how can I change the color of the picture. – askqest Mar 25 '20 at 10:53

0 Answers0