zezo
zezo

Reputation: 455

How to create a subclass of QFileDialog, containing Q_OBJECT macro

Is it possible to subclass a QFileDialog, and override the QObjects with remaining the original slots

from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5.QtGui import *
import sys


class MyQToolButton(QToolButton):
   def __init__(self):
      super().__init()
      
   # a particular QToolbuton different from the current stylesheet
   
class MyFileDialog(QFileDialog):
   def __init__(self):
      super().__init__(filter=filter)
      self.setOption(QFileDialog.DontUseNativeDialog)
      
      """
      How to get each QToolbuton (back, forward, ..., New Folder)
      form the parent class, and override it with the my QToolbutton 'MyQToolButton' 
      somthing like:
      """
      self.back = MyQToolButton()
      self.back.setIcon(QIcon('back.png'))
      self.back.connect(self.backOptionConnected) # maintain the original slots

   def backOptionConnected(self)
      # get the original slot of each option 
      pass     
      
def main():
    app = QApplication(sys.argv)
    dialog = MyFileDialog()
    if dialog.exec_() == QDialog.Accepted:
        print('a subclass of QFileDialog ')


if __name__ == "__main__":
    main()

Upvotes: 0

Views: 291

Answers (1)

musicamante
musicamante

Reputation: 48399

Replacing the buttons with custom subclasses is not a viable option, most importantly because those buttons are connected to internal slots and there's no easy and reliable way to connect the new buttons to them: you could try to hide them and connect the clicked signal of the new buttons to that of the replaced ones, but that's pointless and unnecessarily complicated.

If you need to set specific stylesheets for buttons, then you can just use the proper selectors with the correct object names, and use self.setStyleSheet() with a global style sheet for the dialog, so that you don't need to set them individually.

You can find all those widgets and their object names using findChildren(), and with it you can also know all other widgets, not only the buttons:

for widget in self.findChildren(QWidget):
    if widget.objectName():
        print(widget.__class__.__name__, widget.objectName())

The UI is hardcoded in Qt, so you can even check the source code used for the QFileDialog UI: in the official source tree there is the ui file (which you can save and then load into Designer to see its structure), but you can also read the compiled UI in the woboq browser.

Then it's just a matter of properly create the stylesheet:

    QToolButton#backButton {
        background: transparent;
        border: 1px solid transparent;
        border-radius: 2px;
        qproperty-icon: url('back_icon.png');
        /* since Qt 5.15 you can directly use "icon:" */
    }
    QToolButton#backButton:hover {
        border-style: outset;
        border-color: green;
    }
    ...
}

Upvotes: 1

Related Questions