如何创建 QFileDialog 的子类,包含 Q_OBJECT 宏

How to create a subclass of QFileDialog, containing Q_OBJECT macro

是否可以子类化 QFileDialog,并覆盖 QObjects 并保留原始插槽

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()

用自定义子类替换按钮不是一个可行的选择,最重要的是因为这些按钮连接到内部插槽并且没有简单可靠的方法将新按钮连接到它们:您可以尝试隐藏它们并连接新按钮的 clicked 信号与被替换按钮的信号,但这毫无意义且不必要地复杂化。

如果您需要为按钮设置特定的样式sheet,那么您可以使用正确的 selectors 和正确的对象名称,并使用 self.setStyleSheet() 和全局样式sheet 用于对话框,因此您无需单独设置它们。

您可以使用 findChildren() 找到所有这些小部件及其对象名称,并且您还可以通过它了解所有其他小部件,而不仅仅是按钮:

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

UI 在 Qt 中是硬编码的,因此您甚至可以检查用于 QFileDialog UI 的源代码:在官方源代码树中有 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.

那就只需要正确创建样式了sheet:

    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;
    }
    ...
}