如何修复在python中选择文件后不断重新打开的文件对话框

Posted

技术标签:

【中文标题】如何修复在python中选择文件后不断重新打开的文件对话框【英文标题】:How to fix a file-dialog that keeps reopenning after a file have been choosen in python 【发布时间】:2019-04-18 13:51:23 【问题描述】:

我是 pyqt5 的新手,我需要帮助来关闭我的应用程序中的文件对话框。 UI 是使用 QT 设计器创建的。当我选择一个文件并按下打开按钮时,文件对话框首先关闭,然后再次重新打开。那是我的问题。它不应重新打开。

我尝试在对话框fileDialog.close()fileDialog.hide() 上使用以下这些功能,但未能使其正常工作。

我使用两个不同的文件,一个用于主窗口,另一个用于文件对话框。在主窗口中,我使用以下类

class Main (QtWidgets.QMainWindow):
    def __init__(self):
        super(Main, self).__init__()
        uic.loadUi('MainWindow.ui', self)

        self.btnChooseFile.clicked.connect(self.chooseFile)

    def chooseFile(self):
        fileDialog = OpenFileDialog.FileDialog()
        fileDialog.openFileNameDialog()

app = QtWidgets.QApplication([])
win = Main()
win.show()
sys.exit(app.exec())

另一个类看起来叫做OpenFileDialog.py,看起来像这样:

class FileDialog(QWidget):

    def __init__(self):
        super(FileDialog, self).__init__()
        self.title = 'Choose image-file'
        self.left = 10
        self.top = 10
        self.width = 640
        self.height = 480
        self.initUI()

    def initUI(self):
        self.setWindowTitle(self.title)
        self.setGeometry(self.left, self.top, self.width, self.height)

        self.openFileNameDialog()
        self.openFileNamesDialog()
        self.saveFileDialog()

        self.show()

    def openFileNameDialog(self):    
        options = QFileDialog.Options()
        options |= QFileDialog.DontUseNativeDialog
        fileName, _ = QFileDialog.getOpenFileName(self,"QFileDialog.getOpenFileName()", "","All Files (*);;Python Files (*.py)", options=options)
        if fileName:
            print(fileName)


    def openFileNamesDialog(self):    
        options = QFileDialog.Options()
        options |= QFileDialog.DontUseNativeDialog
        files, _ = QFileDialog.getOpenFileNames(self,"QFileDialog.getOpenFileNames()", "","All Files (*);;Python Files (*.py)", options=options)
        if files:
            print(files)


    def saveFileDialog(self):    
        options = QFileDialog.Options()
        options |= QFileDialog.DontUseNativeDialog
        fileName, _ = QFileDialog.getSaveFileName(self,"QFileDialog.getSaveFileName()","","All Files (*);;Text Files (*.txt)", options=options)
        if fileName:
            print(fileName)


if __name__ == '__main__':
    app = QApplication(sys.argv)
    ex = FileDialog()
    sys.exit(app.exec_()) 

UI 文件如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>winMain</class>
 <widget class="QMainWindow" name="winMain">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>280</width>
    <height>320</height>
   </rect>
  </property>
  <property name="minimumSize">
   <size>
    <width>280</width>
    <height>320</height>
   </size>
  </property>
  <property name="maximumSize">
   <size>
    <width>280</width>
    <height>320</height>
   </size>
  </property>
  <property name="windowTitle">
   <string>OCR</string>
  </property>
  <widget class="QWidget" name="centralwidget">
   <widget class="QPushButton" name="btnChooseFile">
    <property name="geometry">
     <rect>
      <x>80</x>
      <y>10</y>
      <width>93</width>
      <height>28</height>
     </rect>
    </property>
    <property name="text">
     <string>Choose file</string>
    </property>
   </widget>

   <widget class="QLabel" name="lblFile">
    <property name="geometry">
     <rect>
      <x>40</x>
      <y>40</y>
      <width>31</width>
      <height>16</height>
     </rect>
    </property>
    <property name="text">
     <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;File:&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
    </property>
   </widget>
   <widget class="QLabel" name="lblFilePath">
    <property name="geometry">
     <rect>
      <x>40</x>
      <y>60</y>
      <width>221</width>
      <height>16</height>
     </rect>
    </property>
    <property name="text">
     <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-style:italic;&quot;&gt;FilePath&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
    </property>
   </widget>
  </widget>
  <widget class="QMenuBar" name="menubar">
   <property name="geometry">
    <rect>
     <x>0</x>
     <y>0</y>
     <width>280</width>
     <height>26</height>
    </rect>
   </property>
  </widget>
  <widget class="QStatusBar" name="statusbar"/>
 </widget>
 <resources/>
 <connections/>
</ui>

我该如何解决这个问题?

编辑 我通过删除选择文件函数中的以下代码行来解决问题:

fileDialog.openFileNameDialog()

【问题讨论】:

@user9402680 我不确定我理解你的意思。如果我在 initUI 函数中删除这三行中的两行,那么它不会重新打开一次以上? @user9402680 还是谢谢你!我也尝试过,但也没有用。 @user9402680 self.btnChooseFile.clicked.connect(self.chooseFile) 这是我用来将按钮连接到特定功能的方式。我应该换一种方式吗? 老实说,我没有解决你的问题的线索。我建议你也上传你的ui文件,因为只有这些代码是不可执行的。更多知识的人会回答。对不起,我帮不了你,我会删除我的评论。 【参考方案1】:

试试看:

ma​​un.py

import sys
import os                                              # +++
from PyQt5 import QtCore, QtGui, QtWidgets, uic
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *


class FileDialog(QWidget):
    def __init__(self):
        super(FileDialog, self).__init__()
        self.initUI()

    def initUI(self):
        self.setWindowTitle('Choose image-file')
        self.setGeometry(100, 100, 640, 480)

#        self.openFileNameDialog()
#        self.openFileNamesDialog()
#        self.saveFileDialog()

    def openFileNameDialog(self):    
        options = QFileDialog.Options()
        options |= QFileDialog.DontUseNativeDialog
        fileName, _ = QFileDialog.getOpenFileName(self,
                      "QFileDialog.getOpenFileName()", 
                      "",
                      "All Files (*);;Python Files (*.py)", 
                      options=options)
        if fileName:
            print("fileName->", fileName)
            return fileName                                      # +++

    def openFileNamesDialog(self):    
        options = QFileDialog.Options()
        options |= QFileDialog.DontUseNativeDialog
        files, _ = QFileDialog.getOpenFileNames(self,
                   "QFileDialog.getOpenFileNames()", 
                   "",
                   "All Files (*);;Python Files (*.py)", 
                   options=options)
        if files:
            print("files -->>", files)
            return files                                          # +++

    def saveFileDialog(self):    
        options = QFileDialog.Options()
        options |= QFileDialog.DontUseNativeDialog
        fileName, _ = QFileDialog.getSaveFileName(self,
                      "QFileDialog.getSaveFileName()",
                      "",
                      "All Files (*);;Text Files (*.txt)", 
                      options=options)
        if fileName:
            print("save fileName->", fileName)
            return fileName                                        # +++


class Main(QtWidgets.QMainWindow):
    def __init__(self):
        super(Main, self).__init__()

        uic.loadUi('MainWindow.ui', self)

        self.btnChooseFile.clicked.connect(self.chooseFile)
        self.btnChooseFile_2.clicked.connect(self.chooseFiles)     # +++
        self.btnChooseFile_3.clicked.connect(self.saveFile)        # +++

    def chooseFile(self):
#        fileDialog = OpenFileDialog.FileDialog()
        fileDialog = FileDialog()
        fileName = fileDialog.openFileNameDialog()
        self.lblFile.setText( "<b>File:</b> ".format( os.path.basename(fileName) ))
        self.lblFilePath.setText( "<b>FilePath:</b> ".format( os.path.dirname(fileName) ))

    def chooseFiles(self):
        fileDialog = FileDialog()
        files = fileDialog.openFileNamesDialog()
        fileNames = ", ".join([ os.path.basename(fileName) for fileName in files ])
        self.lblFile.setText( "<b>Files:</b> ".format( os.path.basename(fileNames) ))
        self.lblFilePath.setText( "<b>FilePath:</b> ".format( os.path.dirname(files[0]) ))    

    def saveFile(self):
        fileDialog = FileDialog()
        fileName = fileDialog.saveFileDialog()
        self.lblFile.setText( "<b>Save File:</b> ".format( os.path.basename(fileName) ))
        self.lblFilePath.setText( "<b>FilePath:</b> ".format( os.path.dirname(fileName) ))    


if __name__ == '__main__':
    app = QtWidgets.QApplication([])
    win = Main()
    win.show()
    sys.exit(app.exec())

MainWindow.ui

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>winMain</class>
 <widget class="QMainWindow" name="winMain">
  <property name="enabled">
   <bool>true</bool>
  </property>
  <property name="minimumSize">
   <size>
    <width>380</width>
    <height>380</height>
   </size>
  </property>
  <property name="maximumSize">
   <size>
    <width>380</width>
    <height>320</height>
   </size>
  </property>
  <property name="windowTitle">
   <string>OCR</string>
  </property>
  <widget class="QWidget" name="centralwidget">
   <widget class="QPushButton" name="btnChooseFile">
    <property name="geometry">
     <rect>
      <x>10</x>
      <y>10</y>
      <width>93</width>
      <height>28</height>
     </rect>
    </property>
    <property name="text">
     <string>Choose file</string>
    </property>
   </widget>
   <widget class="QLabel" name="lblFile">
    <property name="geometry">
     <rect>
      <x>30</x>
      <y>70</y>
      <width>321</width>
      <height>16</height>
     </rect>
    </property>
    <property name="text">
     <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;File:&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
    </property>
   </widget>
   <widget class="QLabel" name="lblFilePath">
    <property name="geometry">
     <rect>
      <x>30</x>
      <y>100</y>
      <width>321</width>
      <height>16</height>
     </rect>
    </property>
    <property name="text">
     <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-style:italic;&quot;&gt;FilePath&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
    </property>
   </widget>
   <widget class="QPushButton" name="btnChooseFile_2">
    <property name="geometry">
     <rect>
      <x>140</x>
      <y>10</y>
      <width>93</width>
      <height>28</height>
     </rect>
    </property>
    <property name="text">
     <string>Choose files</string>
    </property>
   </widget>
   <widget class="QPushButton" name="btnChooseFile_3">
    <property name="geometry">
     <rect>
      <x>260</x>
      <y>10</y>
      <width>93</width>
      <height>28</height>
     </rect>
    </property>
    <property name="text">
     <string>Save file</string>
    </property>
   </widget>
  </widget>
  <widget class="QMenuBar" name="menubar">
   <property name="geometry">
    <rect>
     <x>0</x>
     <y>0</y>
     <width>380</width>
     <height>21</height>
    </rect>
   </property>
  </widget>
  <widget class="QStatusBar" name="statusbar"/>
 </widget>
 <resources/>
 <connections/>
</ui>

【讨论】:

非常感谢!这完美地工作并且还解决了我在将完整路径添加到“FilePath”标签时遇到的问题【参考方案2】:

如果你需要一个标准的文件对话框,你不必在设计器中设计它或制作一个单独的类。

你要做的就是

    在 Main 中导入 QFileDialog

    编写一个可以打开标准文件对话框的函数:

def open_file_dialog(self):
    # Just this line will open a standard file dialog for you
    res = QFileDialog.getOpenFileName(QFileDialog(self), # parent 
                                      "Select file", # Dialog title
                                      "/some/path/to/open/by/default",
                                      "JPEG Image (*.jpeg)") # filter

    # Once you reach here - dialog will be closed
    if res == ('', ''):
        print("Cancelled")
    else:
        self.process_result(res)
    将按钮点击事件与上面的函数联系起来,就像你做的那样。

【讨论】:

以上是关于如何修复在python中选择文件后不断重新打开的文件对话框的主要内容,如果未能解决你的问题,请参考以下文章

QFileDialog 不断重新打开

EXCEL文件打开乱码,xls格式的,如何修复?

excel文件损坏打不开怎么办

EXCEL打开是一片空白,要从开始选择文件才能打开表格,请问大神们如何修复才能直接打开表格呢?

ubuntu+Windows10双系统安装后卸载ubuntu重新安装grub报错修复

pycharm意外实参怎么修复