3

I created my own class of a Two State button that inherits QPushButton so that it can compress when clicked on. Anyways, I used a horizontal layout in my main window to take care of resizing my buttons, but I'm running into a problem when I try to resize the window while I have an icon on my TwoStateButton. The button itself gets resized correctly, but the icon on top of it does not. I've experimented with QResizeEvent but am not really sure how to use it. I copied my eventFilter method from the online documentation, but it was originally written in C++ so there's currently some syntax errors. How can I fix my code so that the icon on my button gets resized along with the button itself?

from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWidgets import QMainWindow
from PyQt5.QtCore import QEvent
from PyQt5.Qt import QResizeEvent


class TwoStateButton(QtWidgets.QPushButton):

    def __init__(self, on, hover, parent=None):
        super(TwoStateButton, self).__init__(parent)
        self.setIcon(QtGui.QIcon(on))
        self.on = on
        self.hover = hover


    def mousePressEvent(self, event):
        super(TwoStateButton, self).mousePressEvent(event)
        self.setIcon(QtGui.QIcon(self.hover))

    def mouseReleaseEvent(self, event):
        super(TwoStateButton, self).mouseReleaseEvent(event)
        self.setIcon(QtGui.QIcon("%s" % (self.on)))

    def eventFilter(self, obj, event):
        if (event.type() == QEvent.Resize):
            print("\nRESIZING\n")
            self.setIconSize(QResizeEvent.size(self))



class Ui_MainWindow(QMainWindow):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(1090, 681)
        MainWindow.setStyleSheet("")
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")


        self.horizontalLayout = QtWidgets.QHBoxLayout(self.centralwidget)
        self.horizontalLayout.setObjectName("horizontalLayout")


        self.pushButton_2 = TwoStateButton("images/Button5-3.png", "images/Button5-4.png", self.centralwidget)
        self.pushButton_2.setGeometry(QtCore.QRect(430, 310, 141, 81))
        self.pushButton_2.setText("")
        self.pushButton_2.setIconSize(QtCore.QSize(200, 200))
        self.pushButton_2.setCheckable(False)
        self.pushButton_2.setObjectName("pushButton_2")

        self.pushButton_2.installEventFilter(self.pushButton_2)

        self.horizontalLayout.addWidget(self.pushButton_2)


        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtWidgets.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 1090, 22))
        self.menubar.setObjectName("menubar")
        MainWindow.setMenuBar(self.menubar)
        self.statusbar = QtWidgets.QStatusBar(MainWindow)
        self.statusbar.setStyleSheet("border-image: url(:/images/Button5-3.png)")
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)


if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)
    MainWindow = QtWidgets.QMainWindow()
    ui = Ui_MainWindow()
    ui.setupUi(MainWindow)
    MainWindow.show()
    sys.exit(app.exec_())

Besides not resizing the icon, I'm getting the following error message:

TypeError: invalid result from TwoStateButton.eventFilter(), a 'bool' is expected not 'NoneType'
eyllanesc
  • 235,170
  • 19
  • 170
  • 241
  • 1) change `self.setIconSize(QResizeEvent.size(self))` to `self.setIconSize(self.size())` 2) add `return super(TwoStateButton, self).eventFilter(obj, event)` after `self.setIconSize(self.size())` – eyllanesc Jun 13 '19 at 19:05
  • Although I find it unnecessary to use eventFilter, it is easier to use resizeEvent: `def resizeEvent(self, event): self.setIconSize(self.size()) super(TwoStateButton, self).resizeEvent(event)` – eyllanesc Jun 13 '19 at 19:08
  • The changes keep freezing my VM. Is the problem with my computer or the code? Could you please try it on your machine to see – Sherief El-Ghazawi Jun 13 '19 at 19:12
  • I just did it on my friend's computer and it's also crashing, could you please test the code to verify? – Sherief El-Ghazawi Jun 13 '19 at 19:19
  • Is that you are creating an infinite loop, the button size takes into account the size of the icon, if the size of the icon is small the button does not take it into account, but if it is larger the same button will try to enlarge to show the icon , but you are changing the size of the icon, so the button will change its size but before you return it changes the size of the icon, and the button changes its size, etc. It will not stop changing its size until there is a balance so maybe your OS freezes – eyllanesc Jun 13 '19 at 19:23
  • [cont.] I have added a duplicate more than this is the solution to the underlying problem. https://stackoverflow.com/questions/31742194/dynamically-resize-qicon-without-calling-setsizeicon – eyllanesc Jun 13 '19 at 19:23
  • I read through the post and tried implementing all the suggestions but they cause more errors than the original code. Also, the code that I mentioned would freeze my computer would freeze as soon as it's compiled without me even trying to resize it. Both the resizeEvent() method and the changes to eventFilter() resulted in the infinite loop. Do you have any code that ran for you that achieved what I'm trying to do? I've been running into endless errors and tried several suggestions but none have seemed to work for me :( – Sherief El-Ghazawi Jun 13 '19 at 20:19
  • It seems that you just want to copy and paste and not analyze, I have made the adaptation to PyQt5 https://gist.github.com/eyllanesc/5541c53e7e0c4de96f5a601ad28d9b29 – eyllanesc Jun 13 '19 at 20:28
  • I ran the code and tried tinkering with it but the icon does not resize with the button. When I make the window smaller, the button gets smaller with it, but the icon does not. – Sherief El-Ghazawi Jun 13 '19 at 20:53
  • Test with the updated code – eyllanesc Jun 13 '19 at 20:56
  • I tried it with the code you provided via the github link. I'm not sure if it was tested but it's not working for me. Thanks for all the help you've given so far, it's really appreciated – Sherief El-Ghazawi Jun 13 '19 at 23:25

0 Answers0