Как исправить диалоговое окно файла, которое продолжает открываться после выбора файла в python

#python-3.x #pyqt #pyqt5

#python-3.x #pyqt #pyqt5

Вопрос:

я новичок в pyqt5, и мне нужна помощь в закрытии диалогового окна файла в моем приложении. Пользовательский интерфейс создается с помощью QT designer. Когда я выбираю файл и нажимаю кнопку открыть, диалоговое окно файла сначала закрывается, но затем снова открывается. Это моя проблема. Он не должен открываться повторно.

Я пытался использовать следующие функции в диалоговом 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_()) 
 

Файл пользовательского интерфейса выглядит следующим образом:

 <?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>amp;<htmlamp;>amp;<head/amp;>amp;<bodyamp;>amp;<pamp;>amp;<span style=amp;quot; font-weight:600;amp;quot;amp;>File:amp;</spanamp;>amp;</pamp;>amp;</bodyamp;>amp;</htmlamp;></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>amp;<htmlamp;>amp;<head/amp;>amp;<bodyamp;>amp;<pamp;>amp;<span style=amp;quot; font-style:italic;amp;quot;amp;>FilePathamp;</spanamp;>amp;</pamp;>amp;</bodyamp;>amp;</htmlamp;></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()
 

Комментарии:

1. @user9402680 Я не уверен, что понимаю, что вы имеете в виду. Если я удалю две из этих трех строк в функции initUI, то она не будет открываться повторно более одного раза?

2. @user9402680 Спасибо в любом случае! Я пытался сделать то же самое, но и это не сработало.

3. @user9402680 self.btnChooseFile.clicked.connect(self.chooseFile) я использую этот способ для подключения кнопки к определенной функции. Должен ли я сделать это по-другому?

4. Честно говоря, я понятия не имею, как решить вашу проблему. Я рекомендую вам также загрузить свой файл пользовательского интерфейса, потому что только эти коды не являются исполняемыми. Ответят более осведомленные люди. Извините, я не могу вам помочь, я удалю свой комментарий.

Ответ №1:

Попробуйте:

maun.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>amp;<htmlamp;>amp;<head/amp;>amp;<bodyamp;>amp;<pamp;>amp;<span style=amp;quot; font-weight:600;amp;quot;amp;>File:amp;</spanamp;>amp;</pamp;>amp;</bodyamp;>amp;</htmlamp;></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>amp;<htmlamp;>amp;<head/amp;>amp;<bodyamp;>amp;<pamp;>amp;<span style=amp;quot; font-style:italic;amp;quot;amp;>FilePathamp;</spanamp;>amp;</pamp;>amp;</bodyamp;>amp;</htmlamp;></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>
 

введите описание изображения здесь

Комментарии:

1. Большое вам спасибо! Это сработало отлично, а также устранило проблему, с которой я столкнулся, добавив полный путь к ярлыку ‘FilePath’

Ответ №2:

Вам не нужно создавать его в конструкторе или создавать отдельный класс, если вам нужен стандартный файловый диалог.

Все, что вам нужно сделать, это

  1. импортируйте QFileDialog в свой основной
  2. Напишите единственную функцию, которая откроет стандартное диалоговое окно файла:
 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)
 
  1. Соедините событие нажатия кнопки с функцией, описанной выше, так же, как вы это делаете.