Как открыть окно из другого, который уже открыт? - PullRequest
0 голосов
/ 14 октября 2018

У меня есть файл с 2 классами, определяющими пользовательский интерфейс: основной и дополнительный.У меня есть основная программа, которая импортирует из этого main_GUI.py:

from main_GUI import Ui_Dodaj_Ksiazke
from main_GUI import Ui_dodaj_autora

и показывает главное окно:

class Main(QtWidgets.QMainWindow,Ui_Dodaj_Ksiazke):
    def __init__(self):
       QtWidgets.QMainWindow.__init__(self)
       self.ui = Ui_Dodaj_Ksiazke()
       self.ui.setupUi(self)

В какой-то момент в программе я определил функцию, где, если пользователь выбираетопределенная опция из списка открывает новое окно (2-й класс в GUI.py):

def autorchange(self):

    item = self.ui.autor.currentText()
    nazwisko, imie = item.split()
    if item == "Dodaj autora...":
        #this is where program is supposed to show second window for user to interact with

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

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

Я пытался использовать, так же, как и для основного окна, ноэто не удалось с ошибкой:

QLayout: Attempting to add QLayout "" to Main "dodaj_autora", which already has a layout Traceback (most recent call last):   File "C:\Users\jakub\PycharmProjects\biblioteka\main.py", line 46, in autorchange
    self.ui.setupUi(self)   File "C:\Users\jakub\PycharmProjects\biblioteka\main_GUI.py", line 231, in setupUi
    self.buttonBox.accepted.connect(dodaj_autora.accept) AttributeError: 'Main' object has no attribute 'accept'

Я также попробовал другой подход.Я создал новый класс:

class Autor(QtWidgets.QMainWindow,Ui_dodaj_autora):
    def __init__(self):
       QtWidgets.QMainWindow.__init__(self)
       self.ui = Ui_dodaj_autora()
       self.ui.setupUi(self)

Затем внутри класса Main и определения функции проверяем, какая опция из списка была выбрана пользователем:

def autorchange(self):

    item = self.ui.autor.currentText()
    nazwisko, imie = item.split()
    if item == "Dodaj autora...":
        print("Dodawanie autora")
        okno = Autor()
        okno.show()
return item

Но это также заканчивается ошибкой:

QLayout: Attempting to add QLayout "" to Autor "dodaj_autora", which already has a layout

Я подготовил минимальный код, необходимый для запуска программы.Его можно найти здесь: debug.py

import sys
from PyQt5 import QtCore, QtGui, QtWidgets
from debug_GUI import Ui_Dodaj_Ksiazke
from debug_GUI import Ui_dodaj_autora


class Autor(QtWidgets.QMainWindow,Ui_dodaj_autora):
    def __init__(self):
       QtWidgets.QMainWindow.__init__(self)
       self.ui = Ui_dodaj_autora()
       self.ui.setupUi(self)

class Main(QtWidgets.QMainWindow,Ui_Dodaj_Ksiazke):
    def __init__(self):
       QtWidgets.QMainWindow.__init__(self)
       self.ui = Ui_Dodaj_Ksiazke()
       self.ui.setupUi(self)

    def pole_autor(self):

        self.ui.autor.addItem("Wybierz autora...")
        self.ui.autor.addItem("Dodaj autora...")

        self.ui.autor.currentIndexChanged.connect(self.autorchange)

    def autorchange(self):

        item = self.ui.autor.currentText()

        if item == "Dodaj autora...":
            print("Dodawanie autora")
            okno = Autor()
            okno.show()
        return item

if __name__ == "__main__":
    app = QtWidgets.QApplication(sys.argv)
    window = Main()
    window.pole_autor()
    window.show()
    sys.exit(app.exec_())

и debug_GUI.py

from PyQt5 import QtCore, QtWidgets

class Ui_Dodaj_Ksiazke(object):
    def setupUi(self, Dodaj_Ksiazke):
        Dodaj_Ksiazke.setObjectName("Dodaj_Ksiazke")
        Dodaj_Ksiazke.resize(450, 600)
        Dodaj_Ksiazke.setMaximumSize(QtCore.QSize(450, 600))
        self.centralwidget = QtWidgets.QWidget(Dodaj_Ksiazke)
        self.centralwidget.setObjectName("centralwidget")
        self.gridLayout = QtWidgets.QGridLayout(self.centralwidget)
        self.gridLayout.setObjectName("gridLayout")
        self.gridLayout_2 = QtWidgets.QGridLayout()
        self.gridLayout_2.setObjectName("gridLayout_2")

        self.label = QtWidgets.QLabel(self.centralwidget)
        self.label.setObjectName("label")
        self.gridLayout_2.addWidget(self.label, 3, 0, 1, 1)

        self.autor = QtWidgets.QComboBox(self.centralwidget)
        self.autor.setObjectName("autor")
        self.gridLayout_2.addWidget(self.autor, 3, 2, 1, 1)

        Dodaj_Ksiazke.setCentralWidget(self.centralwidget)

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

    def retranslateUi(self, Dodaj_Ksiazke):
        _translate = QtCore.QCoreApplication.translate
        Dodaj_Ksiazke.setWindowTitle(_translate("Dodaj_Ksiazke", "Dodaj Książkę"))
        self.label.setText(_translate("Dodaj_Ksiazke", "Autor"))

class Ui_dodaj_autora(object):
    def setupUi(self, dodaj_autora):
        dodaj_autora.setObjectName("dodaj_autora")
        dodaj_autora.resize(400, 100)
        dodaj_autora.setMaximumSize(QtCore.QSize(400, 100))
        self.verticalLayout = QtWidgets.QVBoxLayout(dodaj_autora)
        self.verticalLayout.setObjectName("verticalLayout")
        self.gridLayout = QtWidgets.QGridLayout()
        self.gridLayout.setObjectName("gridLayout")
        self.label_2 = QtWidgets.QLabel(dodaj_autora)
        self.label_2.setObjectName("label_2")
        self.gridLayout.addWidget(self.label_2, 1, 0, 1, 1)
        self.label = QtWidgets.QLabel(dodaj_autora)
        self.label.setObjectName("label")
        self.gridLayout.addWidget(self.label, 0, 0, 1, 1)
        self.lineEdit = QtWidgets.QLineEdit(dodaj_autora)
        self.lineEdit.setObjectName("lineEdit")
        self.gridLayout.addWidget(self.lineEdit, 0, 1, 1, 1)
        self.lineEdit_2 = QtWidgets.QLineEdit(dodaj_autora)
        self.lineEdit_2.setObjectName("lineEdit_2")
        self.gridLayout.addWidget(self.lineEdit_2, 1, 1, 1, 1)
        self.verticalLayout.addLayout(self.gridLayout)
        self.buttonBox = QtWidgets.QDialogButtonBox(dodaj_autora)
        self.buttonBox.setOrientation(QtCore.Qt.Horizontal)
        self.buttonBox.setStandardButtons(QtWidgets.QDialogButtonBox.Cancel|QtWidgets.QDialogButtonBox.Ok)
        self.buttonBox.setObjectName("buttonBox")
        self.verticalLayout.addWidget(self.buttonBox)

        self.retranslateUi(dodaj_autora)

    def retranslateUi(self, dodaj_autora):
        _translate = QtCore.QCoreApplication.translate
        dodaj_autora.setWindowTitle(_translate("dodaj_autora", "Dodaj Autora"))
        self.label_2.setText(_translate("dodaj_autora", "Nazwisko"))
        self.label.setText(_translate("dodaj_autora", "Imię"))

Вам необходимо щелкнуть раскрывающийся список и выбрать «Добавить автора ...».Это должно открыть новое окно, которое определено в debug_GUI.py - это класс "Ui_dodaj_autora"

https://bitbucket.org/snippets/hyperqbe/rezEBa - GUI https://bitbucket.org/snippets/hyperqbe/Ee9gGE - основная программа

1 Ответ

0 голосов
/ 16 октября 2018

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

  • Ваш код избыточен при наследовании:

    [1.] class Main(QtWidgets.QMainWindow, Ui_Dodaj_Ksiazke): 
    [2.]     def __init__(self):
    [3.]        QtWidgets.QMainWindow.__init__(self)
    [4.]        self.ui = Ui_Dodaj_Ksiazke()
    [5.]        self.ui.setupUi(self)
    

В строке [1.] вы наследуете от Ui_dodaj_autora, а в строке [4.] вы создаете объект класса, зачем вы это делаете?, это не имеет смысла, поэтому вы должны воспользоваться одним из следующих 2 вариантов:

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

class Main(QtWidgets.QMainWindow):
    def __init__(self):
        super(Main, self).__init__()
        self.ui = Ui_Dodaj_Ksiazke()
        self.ui.setupUi(self)
  • С другой стороны, когда вы используете Qt Designer, вы выбираете шаблоны, поэтому, когда вы хотите использовать класс, он должен соответствовать этому выбору, например, вв случае Ui_Dodaj_Ksiazke вы использовали шаблон главного окна, поэтому вы должны использовать QMainWindow, в случае Ui_dodaj_autora вы использовали диалог с кнопками снизу , поэтому вы должны использовать QDialog.

  • QDialogButtonBox должен подключить принятый и отклоненный сигнал к слотам приема и отклонения QDialog.

  • При использовании QDialog, который служит длядиалоговое окно, чтобы попросить пользователя предоставить данные, вы должны использовать exec_(), чтобы знать, есликвест принят или нет.

Учитывая вышеизложенное, получается следующий ответ:

import sys
from PyQt5 import QtCore, QtGui, QtWidgets
from debug_GUI import Ui_Dodaj_Ksiazke, Ui_dodaj_autora


class Autor(QtWidgets.QDialog, Ui_dodaj_autora):
    def __init__(self):
        super(Autor, self).__init__()
        self.setupUi(self)
        self.buttonBox.accepted.connect(self.accept)
        self.buttonBox.rejected.connect(self.reject)


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

    def pole_autor(self):
        self.autor.addItems(["Wybierz autora...", "Dodaj autora..."])
        self.autor.currentTextChanged.connect(self.autorchange)

    @QtCore.pyqtSlot(str)
    def autorchange(self, text):
        if text == "Dodaj autora...":
            print("Dodawanie autora")
            okno = Autor()
            if okno.exec_() == QtWidgets.QDialog.Accepted:
                print(okno.lineEdit.text(), okno.lineEdit_2.text())


if __name__ == "__main__":
    app = QtWidgets.QApplication(sys.argv)
    window = Main()
    window.pole_autor()
    window.show()
    sys.exit(app.exec_())
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...