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

Что я пытаюсь сделать, так это открыть диалоговое окно из меню главного окна, а в диалоговом окне есть некоторые входные данные, либо linetextedit, либо spinbox, либо поля со списком... И есть одна кнопка, чтобы закрыть диалоговое окно и передать данные в главное окно. В главном окне выполняются некоторые операции. В примере, который я сделал, операции складывания двух чисел из диалогового окна вместе отображаются в главном окне, записываются в txt-файл на локальный диск и открываются с помощью QDesktopServices.

Даже не элегантно, я сделал это, но обнаружил, что в диалоговом окне добавление и отображение, а также открытие внешнего файла по-прежнему выполняются, даже если я закрываю диалоговое окно с помощью 'x' в правом верхнем углу . Я хочу связать функцию только с кнопкой, но не с событием закрытия.

Здесь я вставляю преобразованные файлы py из пользовательского интерфейса, а также основной файл.

mainwindowui.py

from PySide2 import QtCore, QtGui, QtWidgets

class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(486, 497)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.gridLayout = QtWidgets.QGridLayout(self.centralwidget)
        self.gridLayout.setObjectName("gridLayout")
        self.label = QtWidgets.QLabel(self.centralwidget)
        self.label.setObjectName("label")
        self.gridLayout.addWidget(self.label, 0, 0, 1, 1)
        self.lineEdit = QtWidgets.QLineEdit(self.centralwidget)
        self.lineEdit.setObjectName("lineEdit")
        self.gridLayout.addWidget(self.lineEdit, 0, 1, 1, 1)
        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtWidgets.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 486, 22))
        self.menubar.setObjectName("menubar")
        self.menuFile = QtWidgets.QMenu(self.menubar)
        self.menuFile.setObjectName("menuFile")
        MainWindow.setMenuBar(self.menubar)
        self.statusbar = QtWidgets.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)
        self.actionOpenLocal = QtWidgets.QAction(MainWindow)
        self.actionOpenLocal.setObjectName("actionOpenLocal")
        self.menuFile.addAction(self.actionOpenLocal)
        self.menubar.addAction(self.menuFile.menuAction())

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

    def retranslateUi(self, MainWindow):
        MainWindow.setWindowTitle(QtWidgets.QApplication.translate("MainWindow", "MainWindow", None, -1))
        self.label.setText(QtWidgets.QApplication.translate("MainWindow", "Summation", None, -1))
        self.menuFile.setTitle(QtWidgets.QApplication.translate("MainWindow", "File", None, -1))
        self.actionOpenLocal.setText(QtWidgets.QApplication.translate("MainWindow", "OpenLocal", None, -1))

диалогуи.py

from PySide2 import QtCore, QtGui, QtWidgets

class Ui_Dialog(object):
    def setupUi(self, Dialog):
        Dialog.setObjectName("Dialog")
        Dialog.resize(320, 237)
        self.gridLayout = QtWidgets.QGridLayout(Dialog)
        self.gridLayout.setObjectName("gridLayout")
        self.labelA = QtWidgets.QLabel(Dialog)
        self.labelA.setObjectName("labelA")
        self.gridLayout.addWidget(self.labelA, 0, 0, 1, 1)
        self.alineEdit = QtWidgets.QLineEdit(Dialog)
        self.alineEdit.setObjectName("alineEdit")
        self.gridLayout.addWidget(self.alineEdit, 0, 1, 1, 1)
        self.labelB = QtWidgets.QLabel(Dialog)
        self.labelB.setObjectName("labelB")
        self.gridLayout.addWidget(self.labelB, 1, 0, 1, 1)
        self.blineEdit = QtWidgets.QLineEdit(Dialog)
        self.blineEdit.setObjectName("blineEdit")
        self.gridLayout.addWidget(self.blineEdit, 1, 1, 1, 1)
        self.pushButton = QtWidgets.QPushButton(Dialog)
        self.pushButton.setObjectName("pushButton")
        self.gridLayout.addWidget(self.pushButton, 2, 0, 1, 2)

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

    def retranslateUi(self, Dialog):
        Dialog.setWindowTitle(QtWidgets.QApplication.translate("Dialog", "Dialog", None, -1))
        self.labelA.setText(QtWidgets.QApplication.translate("Dialog", "inputA", None, -1))
        self.labelB.setText(QtWidgets.QApplication.translate("Dialog", "inputB", None, -1))
        self.pushButton.setText(QtWidgets.QApplication.translate("Dialog", "OpenPdf", None, -1)) 

и main.py

import sys
import os

from PySide2 import QtCore, QtGui, QtWidgets
from mainwindowui import Ui_MainWindow
from dialogui import Ui_Dialog


class fileDialog(QtWidgets.QDialog,Ui_Dialog):
    def __init__(self,parent):
        super().__init__(parent)
        self.setupUi(self)
        self.setWindowTitle("Open File")
        QtCore.QObject.connect(self.pushButton, QtCore.SIGNAL("clicked()"), self.close)


class MainWindow(QtWidgets.QMainWindow,Ui_MainWindow):
    def __init__(self):
        super().__init__()
        self.setupUi(self)
        self.actionOpenLocal.triggered.connect(self.startDialog)
        self.show()

    def startDialog(self):
        dlg = fileDialog(self)
        dlg.exec_()
        dlg.pushButton.clicked.connect(self.getDialogInfo(dlg))


    def getDialogInfo(self,dialogue):
        self.avalue = float(dialogue.alineEdit.text())
        self.bvalue = float(dialogue.blineEdit.text())
        sum = str(self.avalue+self.bvalue)
        self.lineEdit.setText(sum)
        file = open("result.txt","w")
        file.write(sum)
        file.close()

        QtGui.QDesktopServices.openUrl(QtCore.QUrl.fromLocalFile(currentdir +"/result.txt"))


if __name__=='__main__':
    app = QtWidgets.QApplication(sys.argv)
    currentdir = os.getcwd()
    mainWin = MainWindow()
    ret = app.exec_()
    sys.exit(ret)

А также, если кто-то может исправить части, которые кажутся не такими стандартными, я также очень признателен.


person seasoul    schedule 12.10.2018    source источник


Ответы (2)


В вашем коде есть несколько ошибок:

  • Строка dlg.pushButton.clicked.connect(self.getDialogInfo(dlg)) не имеет смысла, давайте немного проанализируем, какой результат имеет self.getDialogInfo(dlg), функция getDialogInfo выполняет задачу, но не возвращает ничего, равного возвращению None, поэтому исходный код равен dlg.pushButton.clicked.connect(None), он выполняет задачу, которую вы хотите, но соединение не нужно.

  • Диалог возвращает код, когда вы вызываете exec_(), и он используется для определения того, принята задача или нет, поскольку это задача диалогового окна. Этот код возвращается только тогда, когда вы вызываете метод accept() или reject(), который закрывает окно, поэтому вместо кнопки, вызывающей close(), вы должны вызывать accept(), поэтому, когда вы закрываете окно с помощью кнопки X, он будет внутренне вызывать reject(), так что вы можете различать между каждой кнопкой.

  • Не используйте sum, так как это имя функции и считается зарезервированным словом, это может вызвать проблемы в будущем.

  • Используйте с, чтобы открыть файл, так как он автоматически закрывает файл при выходе из него.

  • Не объединяйте пути вручную, потому что объединение зависит от платформы, вам лучше использовать функции, предоставляемые библиотекой os.

  • Используйте новый синтаксис соединения, он более удобочитаем.

С учетом вышеизложенного получается следующее решение:

import os
import sys

from PySide2 import QtCore, QtGui, QtWidgets

from mainwindowui import Ui_MainWindow
from dialogui import Ui_Dialog


class fileDialog(QtWidgets.QDialog, Ui_Dialog):
    def __init__(self,parent):
        super().__init__(parent)
        self.setupUi(self)
        self.setWindowTitle("Open File")
        self.pushButton.clicked.connect(self.accept)


class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
    def __init__(self):
        super().__init__()
        self.setupUi(self)
        self.actionOpenLocal.triggered.connect(self.startDialog)
        self.show()

    def startDialog(self):
        dlg = fileDialog(self)
        if dlg.exec_() == QtWidgets.QDialog.Accepted:
            self.getDialogInfo(dlg)

    def getDialogInfo(self, dialogue):
        self.avalue = float(dialogue.alineEdit.text())
        self.bvalue = float(dialogue.blineEdit.text())
        res = str(self.avalue+self.bvalue)
        self.lineEdit.setText(res)
        with open("result.txt","w") as file:
            file.write(res)
        QtGui.QDesktopServices.openUrl(QtCore.QUrl.fromLocalFile(os.path.join(currentdir,"result.txt")))


if __name__=='__main__':
    app = QtWidgets.QApplication(sys.argv)
    currentdir = os.getcwd()
    mainWin = MainWindow()
    ret = app.exec_()
    sys.exit(ret)
person eyllanesc    schedule 12.10.2018

Вы можете использовать сигналы и слоты.

import sys
import os

from PySide2 import QtCore, QtGui, QtWidgets
from mainwindowui import Ui_MainWindow
from dialogui import Ui_Dialog


class fileDialog(QtWidgets.QDialog,Ui_Dialog):
    sig_complete = QtCore.Signal(dict)
    def __init__(self,parent):
        super().__init__(parent)
        self.setupUi(self)
        self.setWindowTitle("Open File")
        QtCore.QObject.connect(self.pushButton, QtCore.SIGNAL("clicked()"), self.slt_save)

    def slt_save(self):
        self.sig_complete.emit({"aline": self.alineEdit.text(), "bline": self.blineEdit.text()})
        self.close()

class MainWindow(QtWidgets.QMainWindow,Ui_MainWindow):
    def __init__(self):
        super().__init__()
        self.setupUi(self)
        self.actionOpenLocal.triggered.connect(self.startDialog)
        self.show()

    def startDialog(self):
        dlg = fileDialog(self)
        dlg.sig_complete.connect(self.getDialogInfo)
        dlg.exec_()

    def getDialogInfo(self,data_dict):
        self.avalue = float(data_dict["aline"])
        self.bvalue = float(data_dict["bline"])
        sum = str(self.avalue+self.bvalue)
        self.lineEdit.setText(sum)
        file = open("result.txt","w")
        file.write(sum)
        file.close()
        QtGui.QDesktopServices.openUrl(QtCore.QUrl.fromLocalFile(currentdir +"/result.txt"))


if __name__=='__main__':
    app = QtWidgets.QApplication(sys.argv)
    currentdir = os.getcwd()
    mainWin = MainWindow()
    ret = app.exec_()
    sys.exit(ret)
person Guo Degang    schedule 12.10.2018
comment
Ответ работает как шарм, и я думаю, что использование пользовательского сигнала в этом ответе является мощным и более настраиваемым. Я принимаю ответ @eyllanesc, потому что он провел тщательный анализ, и решение также работает хорошо. - person seasoul; 12.10.2018