【问题标题】:PySide2 v5.12 : Creating a FileDialog on a click of a buttonPySide2 v5.12:单击按钮创建 FileDialog
【发布时间】:2019-08-15 10:46:22
【问题描述】:

我在 QtDesigner 中设计了一个基本的 UI。现在我试图在单击按钮时弹出一个简单的文件对话框,下面给出的是我的 GUI 代码:

from PySide2 import QtCore, QtGui, QtWidgets


class Ui_MainWindow(object):
 def setupUi(self, MainWindow):
.....
.....

  self.input_Image_GraphicsView = QtWidgets.QGraphicsView(self.centralwidget)
  self.input_Image_GraphicsView.setGeometry(QtCore.QRect(730, 110, 480, 320))
  self.input_Image_GraphicsView.setObjectName("input_Image_GraphicsView")
......
  self.output_Image_GraphicsView = QtWidgets.QGraphicsView(self.centralwidget)
  self.output_Image_GraphicsView.setGeometry(QtCore.QRect(730, 480, 480, 320))
  self.output_Image_GraphicsView.setObjectName("output_Image_GraphicsView")
......
  self.file_Select_Btn = QtWidgets.QPushButton(self.centralwidget)
  self.file_Select_Btn.setGeometry(QtCore.QRect(1082, 80, 121, 28))
  self.file_Select_Btn.setObjectName("file_Select_Btn")
  self.file_Select_Btn.clicked.connect(self.selectFile)
.....
.....
 def selectFile():
  self.path_To_File = QtWidgets.QFileDialog.getOpenFileName(self, QtCore.QObject.tr("Load Image"), QtCore.QObject.tr("~/Desktop/"), QtCore.QObject.tr("Images (*.jpg)"))
  print(self.path_To_File)
.....
.....

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

这是我得到的错误:

TypeError: descriptor 'tr' requires a 'PySide2.QtCore.QObject' object but received a 'str'

当我不使用“tr”时,我得到了:

TypeError: 'PySide2.QtWidgets.QFileDialog.getOpenFileName' called with wrong 
argument types:
PySide2.QtWidgets.QFileDialog.getOpenFileName(Ui_MainWindow, str, str, str)
Supported signatures:
PySide2.QtWidgets.QFileDialog.getOpenFileName(PySide2.QtWidgets.QWidget = None, str = '', str = '', str = '', str = '', PySide2.QtWidgets.QFileDialog.Options = Default(QFileDialog.Options))

我已阅读此处给出的 Qt 5.12 版的 python 文档:https://doc.qt.io/qtforpython/PySide2/QtWidgets/QFileDialog.html

那也没有帮助。我哪里做错了??

基本上我想:

  1. 获取文件对话框 -> 选择 JPG 文件
  2. 在 python 代码中获取文件的路径 -> 使用 GUI 上的图像填充 GraphicsView

我目前在这两个方面都在苦苦挣扎

任何帮助将不胜感激..

【问题讨论】:

    标签: python-3.x pyside2 filedialog


    【解决方案1】:

    您不应将您的程序逻辑与生成的 UI 文件混合,而是创建一个 QMainWindow 类包装器并从 QMainWindow 和 UI 类继承。

    根据您的实际问题,在传递要翻译的文本之前,您只是缺少对对象(例如,self)的引用,我在以下示例中添加了一个小帮助方法来处理它:

    import sys
    from PySide2 import QtCore, QtGui, QtWidgets
    from PySide2.QtCore import QObject, QRectF, Qt
    from PySide2.QtWidgets import QMainWindow, QFileDialog, QWidget, QVBoxLayout, QGraphicsScene, QGraphicsView
    from PySide2.QtGui import QPixmap
    
    
    class Ui_MainWindow(object):
        def setupUi(self, MainWindow):
            self.centralWidget = QtWidgets.QWidget(MainWindow)
            self.gridLayout = QtWidgets.QGridLayout(self.centralWidget)
            self.file_Select_Btn = QtWidgets.QPushButton(self.centralWidget)
            self.file_Select_Btn.setGeometry(QtCore.QRect(1082, 80, 121, 28))
            self.file_Select_Btn.setObjectName("file_Select_Btn")
            self.file_Select_Btn.setText("Load Image")
            self.gridLayout.addWidget(self.file_Select_Btn)
            MainWindow.setCentralWidget(self.centralWidget)
    
            QtCore.QMetaObject.connectSlotsByName(MainWindow)
    
    
    class MainWindow(QMainWindow, Ui_MainWindow):
        def __init__(self):
            Ui_MainWindow.__init__(self)
            QMainWindow.__init__(self)
    
            # Initialize UI
            self.setupUi(self)
            self.file_Select_Btn.clicked.connect(self.showImage)
    
        def tr(self, text):
            return QObject.tr(self, text)
    
        def showImage(self):
            path_to_file, _ = QFileDialog.getOpenFileName(self, self.tr("Load Image"), self.tr("~/Desktop/"), self.tr("Images (*.jpg)"))
    
            self.image_viewer = ImageViewer(path_to_file)
            self.image_viewer.show()
    
    
    class ImageViewer(QWidget):
        def __init__(self, image_path):
            super().__init__()
    
            self.scene = QGraphicsScene()
            self.view = QGraphicsView(self.scene)
            layout = QVBoxLayout()
            layout.addWidget(self.view)
            self.setLayout(layout)
    
            self.load_image(image_path)
    
        def load_image(self, image_path):
            pixmap = QPixmap(image_path)
            self.scene.addPixmap(pixmap)
            self.view.fitInView(QRectF(0, 0, pixmap.width(), pixmap.height()), Qt.KeepAspectRatio)
            self.scene.update()
    
    
    if __name__ == "__main__":
        app = QtWidgets.QApplication(sys.argv)
        main_window = MainWindow()
        main_window.show()
        sys.exit(app.exec_())
    

    【讨论】:

    • 感谢您的回复。我将尝试在我的代码中复制您的努力,并会回复您。同时,您能否详细说明您的建议是否有任何具体原因您不应该将您的程序逻辑与生成的 UI 文件混在一起。谢谢。
    • 因为 UI 文件可以被生成器覆盖,然后您将丢失所有特定代码,而且它使程序更易于阅读和维护,因为您可以将外观与逻辑分开,我现在能想到的另一个原因是它允许您为不同的实现(甚至不同的应用程序)重用相同的 UI 文件。
    • +1 感谢您的解决方案非常适合我的问题的第一部分。你能帮我做第二部分吗?谢谢
    • 很抱歉给您添麻烦了,但我在 UI 窗口中有两个 GraphicsView(代码在 qustion 中更新),我希望有一个可以在其中任何一个中加载图像的通用类.谢谢
    • 您还需要添加一个场景,然后在您的 MainWindow 类中简单地实现方法 load_image 并使用相应的 GraphicsView
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多