Открывать окно при нажатии кнопки Pu sh в главном окне PyQt5 Python - PullRequest
1 голос
/ 27 мая 2020

Я просмотрел различные сообщения, похожие на сообщения, в которых есть похожие проблемы, также попробовал ответы, но у меня это не сработало. Итак, вот моя проблема -

У меня есть два windows - TestBox и MailBox, когда я нажимаю кнопку TestBox Pushbutton вместе с аргументом пути ввода, он должен открыть окно MailBox, это новое окно MailBox отправит ModifiedPath в TestBox снова, когда я закрываю окно MailBox

  1. Я создал оба windows в PyQt5 Tool и создал файл ui, а затем преобразовал его в файл Python с помощью - python -m PyQt5.ui c .pyui c testboxui.ui -o testboxui.py

  2. Я не касаюсь файла testboxui.py или mailboxui.py, поскольку они хранятся при изменении любых модификаций, сделанных при повторном преобразовании. Вместо этого я создал еще один файл TestBox.py и MailBox.py для импорта и записи функций.

Вот производимый минимальный код -

TestBox.py [Основное приложение Код]

import os,sys
from PyQt5 import QtWidgets, QtGui, QtCore
from testboxui import Ui_TestBox
from MailBox import AppWindow_MailList

app = QtWidgets.QApplication(sys.argv)

class AppWindow_MainBox(QtWidgets.QMainWindow):
    def __init__(self):
        super(AppWindow_MainBox, self).__init__()
        self.ui = Ui_TestBox()
        self.ui.setupUi(self)
        self.ui.openbox.clicked.connect(self.fcn_maillist)

    def fcn_maillist(self):
        GetPath = os.getcwd()
        dialog  = AppWindow_MailList(self,GetPath)
        if dialog.exec_() == AppWindow_MailList.Accepted:
            GetPath = dialog.get_output()

def main():
    app = QtWidgets.QApplication(sys.argv)
    application = AppWindow_MainBox()
    application.show()
    sys.exit(app.exec_())

if __name__ == '__main__':
    main()

testboxui.py [Создано PyQt5 Tool непосредственно из файла пользовательского интерфейса]

from PyQt5 import QtCore, QtGui, QtWidgets

class Ui_TestBox(object):
    def setupUi(self, TestBox):
        TestBox.setObjectName("TestBox")
        TestBox.resize(647, 279)
        self.centralwidget = QtWidgets.QWidget(TestBox)
        self.centralwidget.setObjectName("centralwidget")
        self.openbox = QtWidgets.QPushButton(self.centralwidget)
        self.openbox.setGeometry(QtCore.QRect(210, 60, 231, 91))
        self.openbox.setObjectName("openbox")
        TestBox.setCentralWidget(self.centralwidget)

        self.retranslateUi(TestBox)
        QtCore.QMetaObject.connectSlotsByName(TestBox)

    def retranslateUi(self, TestBox):
        _translate = QtCore.QCoreApplication.translate
        TestBox.setWindowTitle(_translate("TestBox", "TestBox"))
        self.openbox.setText(_translate("TestBox", "Click Here \n""To Open Another Window"))

MailBox.py [Код дочернего приложения]

import os,sys
from PyQt5 import QtWidgets, QtGui, QtCore
from maillistui import Ui_MailList

app = QtWidgets.QApplication(sys.argv)

class AppWindow_MailList(QtWidgets.QMainWindow):
    def __init__(self,RcvPath=''):
        super(AppWindow_MailList, self).__init__()
        self.ui = Ui_MailList()
        self.ui.setupUi(self)
        self.init_fcn(RcvPath)

    def init_fcn(self,RcvPath):
        self.ui.browse.clicked.connect(self.browse_fcn) 
        if not RcvPath:
            self.RcvPath = os.getcwd()
        else:
            self.RcvPath = RcvPath
        self.ui.path.setText(self.RcvPath)

    def closeEvent(self, event):
        event.accept()

    def get_output(self):
        return os.path.join(self.RcvPath,'TestFolder')

    def browse_fcn(self):
        pass

def main():
    app = QtWidgets.QApplication(sys.argv)
    application = AppWindow_MailList()
    application.show()
    sys.exit(app.exec_())

if __name__ == '__main__':
    main()

maillistui.py - [Производится PyQt5 непосредственно из файла пользовательского интерфейса]

from PyQt5 import QtCore, QtGui, QtWidgets

class Ui_MailList(object):
    def setupUi(self, MailList):
        MailList.setObjectName("MailList")
        MailList.resize(647, 279)
        self.centralwidget = QtWidgets.QWidget(MailList)
        self.centralwidget.setObjectName("centralwidget")
        self.path = QtWidgets.QLineEdit(self.centralwidget)
        self.path.setGeometry(QtCore.QRect(50, 30, 511, 41))
        self.path.setObjectName("path")
        self.browse = QtWidgets.QPushButton(self.centralwidget)
        self.browse.setGeometry(QtCore.QRect(450, 90, 112, 41))
        self.browse.setObjectName("browse")
        MailList.setCentralWidget(self.centralwidget)

        self.retranslateUi(MailList)
        QtCore.QMetaObject.connectSlotsByName(MailList)

    def retranslateUi(self, MailList):
        _translate = QtCore.QCoreApplication.translate
        MailList.setWindowTitle(_translate("MailList", "MailList"))
        self.browse.setText(_translate("MailList", "Browse"))

Раньше я создавал диалог PyQt5 с помощью QtWidgets.QDialog, который я могу легко загрузить в QtWidgets.QApplication. Но здесь оба являются QApplication (QMainWindow), но затрудняет вызов пользовательского интерфейса в пользовательском интерфейсе.

Что-то не так, что я здесь делаю ???

1 Ответ

2 голосов
/ 27 мая 2020

Должно быть создано только одно приложение QApplication, в вашем случае для каждого сценария, который вы создаете 2 без необходимости, удалите следующие коды:

```
from MailBox import AppWindow_MailList

app = QtWidgets.QApplication(sys.argv) # <--- delete this line

class AppWindow_MainBox(QtWidgets.QMainWindow):
```

```
from maillistui import Ui_MailList

app = QtWidgets.QApplication(sys.argv) # <--- delete this line

class AppWindow_MailList(QtWidgets.QMainWindow):
```

При исправлении вышеуказанного возникает другая ошибка, но для этого Python указывает сообщения об ошибках, в случае многих IDE они не обрабатывают ошибки Qt, поэтому я рекомендую вам запустить его в консоли, и вы получите следующее сообщение об ошибке:

Traceback (most recent call last):
  File "TextBox.py", line 16, in fcn_maillist
    dialog  = AppWindow_MailList(self,GetPath)
TypeError: __init__() takes from 1 to 2 positional arguments but 3 were given

Это явно указывает на то, что AppWindow_MailList class принимает один параметр (RcvPath), но вы передаете его 2. Я не знаю, опечатка ли это или вы не знаете, как используется «self» в python (если последнее, то это рекомендуется прочитать Какова цель слова «я»? )

class AppWindow_MailList(QtWidgets.QMainWindow):
    def __init__(self,RcvPath=''):
        super(AppWindow_MailList, self).__init__()

Даже при решении этой ошибки есть еще одна проблема: AppWindow_MailList - это QMainWindow, поэтому у него нет exec_ (), похоже, вы пытались использовать код какого-то сообщения, в котором используется QDialog, не понимая логики c решения.

In gene ral, у каждого виджета есть цель:

  • QWidget - это общий виджет c, который можно использовать в качестве основы для создания любого другого типа виджета или контейнера, аналогично div. в html.

  • QDialog - это виджет, цель которого - запросить информацию у пользователя, поэтому метод exec_ () возвращает статус запроса (если он был принят или отклонено), блокируя событие l oop.

  • Цель QMainWindow - предлагать главное окно, так как оно содержит панели инструментов, строку состояния, строку меню, dockwidets и т. д. c.

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

mailbox.ui

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>Dialog</class>
 <widget class="QDialog" name="Dialog">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>461</width>
    <height>300</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>Dialog</string>
  </property>
  <layout class="QGridLayout" name="gridLayout">
   <item row="0" column="0" colspan="2">
    <widget class="QLineEdit" name="mail_le">
     <property name="minimumSize">
      <size>
       <width>0</width>
       <height>49</height>
      </size>
     </property>
     <property name="maximumSize">
      <size>
       <width>16777215</width>
       <height>40</height>
      </size>
     </property>
    </widget>
   </item>
   <item row="1" column="0">
    <spacer name="horizontalSpacer">
     <property name="orientation">
      <enum>Qt::Horizontal</enum>
     </property>
     <property name="sizeHint" stdset="0">
      <size>
       <width>324</width>
       <height>20</height>
      </size>
     </property>
    </spacer>
   </item>
   <item row="1" column="1">
    <widget class="QPushButton" name="browse_btn">
     <property name="minimumSize">
      <size>
       <width>110</width>
       <height>40</height>
      </size>
     </property>
     <property name="maximumSize">
      <size>
       <width>16777215</width>
       <height>110</height>
      </size>
     </property>
     <property name="text">
      <string>Browse</string>
     </property>
    </widget>
   </item>
   <item row="2" column="1">
    <spacer name="verticalSpacer">
     <property name="orientation">
      <enum>Qt::Vertical</enum>
     </property>
     <property name="sizeHint" stdset="0">
      <size>
       <width>20</width>
       <height>178</height>
      </size>
     </property>
    </spacer>
   </item>
  </layout>
 </widget>
 <resources/>
 <connections/>
</ui>

testbox .ui

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>MainWindow</class>
 <widget class="QMainWindow" name="MainWindow">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>800</width>
    <height>600</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>MainWindow</string>
  </property>
  <widget class="QWidget" name="centralwidget">
   <layout class="QGridLayout" name="gridLayout">
    <item row="0" column="1">
     <spacer name="verticalSpacer">
      <property name="orientation">
       <enum>Qt::Vertical</enum>
      </property>
      <property name="sizeHint" stdset="0">
       <size>
        <width>20</width>
        <height>213</height>
       </size>
      </property>
     </spacer>
    </item>
    <item row="1" column="0">
     <spacer name="horizontalSpacer">
      <property name="orientation">
       <enum>Qt::Horizontal</enum>
      </property>
      <property name="sizeHint" stdset="0">
       <size>
        <width>267</width>
        <height>20</height>
       </size>
      </property>
     </spacer>
    </item>
    <item row="1" column="1">
     <widget class="QPushButton" name="open_btn">
      <property name="minimumSize">
       <size>
        <width>230</width>
        <height>90</height>
       </size>
      </property>
      <property name="maximumSize">
       <size>
        <width>230</width>
        <height>90</height>
       </size>
      </property>
      <property name="text">
       <string>Click Here 
To Open Another Window</string>
      </property>
     </widget>
    </item>
    <item row="1" column="2">
     <spacer name="horizontalSpacer_2">
      <property name="orientation">
       <enum>Qt::Horizontal</enum>
      </property>
      <property name="sizeHint" stdset="0">
       <size>
        <width>267</width>
        <height>20</height>
       </size>
      </property>
     </spacer>
    </item>
    <item row="2" column="1">
     <spacer name="verticalSpacer_2">
      <property name="orientation">
       <enum>Qt::Vertical</enum>
      </property>
      <property name="sizeHint" stdset="0">
       <size>
        <width>20</width>
        <height>212</height>
       </size>
      </property>
     </spacer>
    </item>
   </layout>
  </widget>
  <widget class="QMenuBar" name="menubar">
   <property name="geometry">
    <rect>
     <x>0</x>
     <y>0</y>
     <width>800</width>
     <height>26</height>
    </rect>
   </property>
  </widget>
  <widget class="QStatusBar" name="statusbar"/>
 </widget>
 <resources/>
 <connections/>
</ui>
python -m PyQt5.uic.pyuic mailbox.ui -o mailbox_ui.py -x 
python -m PyQt5.uic.pyuic testbox.ui -o testbox_ui.py -x 

mailbox.py

import os
from PyQt5 import QtCore, QtGui, QtWidgets

from mailbox_ui import Ui_Dialog


class MailBox(QtWidgets.QDialog):
    def __init__(self, mail="", parent=None):
        super().__init__(parent)

        self.ui = Ui_Dialog()
        self.ui.setupUi(self)

        self.ui.browse_btn.clicked.connect(self.accept)

        if mail:
            self.ui.mail_le.setText(mail)
        else:
            self.ui.mail_le.setText(os.getcwd())

    def mail(self):
        return self.ui.mail_le.text()


def main():
    import sys

    app = QtWidgets.QApplication(sys.argv)
    w = MailBox()
    w.show()
    sys.exit(app.exec_())


if __name__ == "__main__":
    main()

testbox.py

import os
from PyQt5 import QtCore, QtGui, QtWidgets

from mailbox import MailBox
from testbox_ui import Ui_MainWindow


class TestBox(QtWidgets.QMainWindow):
    def __init__(self, parent=None):
        super().__init__(parent)

        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)
        self.ui.open_btn.clicked.connect(self.open_window)

    @QtCore.pyqtSlot()
    def open_window(self):
        dialog = MailBox()
        if dialog.exec_() == QtWidgets.QDialog.Accepted:
            path = dialog.mail()
            print(path)


def main():
    import sys

    app = QtWidgets.QApplication(sys.argv)
    w = TestBox()
    w.show()
    sys.exit(app.exec_())


if __name__ == "__main__":
    main()
├── mailbox.py
├── mailbox.ui
├── mailbox_ui.py
├── testbox.py
├── testbox.ui
└── testbox_ui.py
...