Как я могу наследовать между классами в PyQT? - PullRequest
0 голосов
/ 11 марта 2019

Чтобы отслеживать прогресс, это третий вопрос о практике с различными классами в PyQt5. Здесь приведены ссылки на мои предыдущие вопросы: открытие нового окна , Открытие файла из основногоокно в новое окно в PyQt5 (в разных файлах) .

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

ВПервые вопросы Мне предложили, что в качестве альтернативы работе с большим количеством классов они могут наследоваться от QMainWindow, поэтому я искал дополнительную информацию для этого: Наследование классов PyQt

Второй вопроскод работал, но он отображал оба окна одновременно, поэтому этот вопрос: PyQt: как скрыть QMainWindow помог мне написать этот код (я привел это здесь, потому что он немного отличается от того, чтов ссылке, плюс я применяю то, что говорится в ответе):

import sys, os
from PyQt5 import QtGui, QtCore, QtWidgets
from PyQt5.QtWidgets import QApplication, QWidget, QVBoxLayout, QPushButton

class Dialog_02(QtWidgets.QWidget):
    def __init__(self, parent=None):
        super(Dialog_02, self).__init__(parent, QtCore.Qt.Window)

        self.setAttribute(QtCore.Qt.WA_DeleteOnClose)

        myBoxLayout = QVBoxLayout()

        Button_02 = QPushButton ("Show Dialog 01")
        myBoxLayout.addWidget(Button_02)

        self.setLayout(myBoxLayout)
        self.setWindowTitle('Dialog 02')

        Button_02.clicked.connect(self.closeAndReturn)

    def closeAndReturn(self):
        self.close()
        self.parent().show()


class Dialog_01(QtWidgets.QWidget):
    def __init__(self, parent=None):
        super(Dialog_01, self).__init__()

        self.setAttribute(QtCore.Qt.WA_DeleteOnClose)

        myBoxLayout = QVBoxLayout()

        Button_01 = QPushButton ("Show Dialog 02")
        myBoxLayout.addWidget(Button_01)

        self.setLayout(myBoxLayout)
        self.setWindowTitle('Dialog 01')

        Button_01.clicked.connect(self.callAnotherQMainWindow)

    def callAnotherQMainWindow(self):
        self.hide()
        self.dialog_02 = Dialog_02(self)
        self.dialog_02.show()

if __name__ == '__main__':
    app = QApplication(sys.argv)
    dialog_1 = Dialog_01()
    dialog_1.show()
    sys.exit(app.exec_())

В этом коде я не наследую, но он работает нормально.

Проблема в том, что когда япопробуйте использовать тот же синтаксис в исходном коде вопроса, он не запустится, я не уверен, что у меня нормально получается наследство.

import sys
import os
from PyQt5 import QtWidgets, QtGui, QtCore
from PyQt5.QtWidgets import QApplication, QWidget
from PyQt5.QtWidgets import QPushButton, QVBoxLayout, QTextEdit, QHBoxLayout, QLabel, QMainWindow, QAction, QFileDialog

class SecondWindow(QWidget):
    def __init__(self, Window):
        super(SecondWindow, self).__init__(parent, QtCore.Qt.Window)

        self.setAttribute(QtCore.Qt.WA_DeleteOnClose)

        self.text = QTextEdit(self)
        self.btn_return= QPushButton("Return")
        self.init_ui()

    def init_ui(self):
        v_layout = QVBoxLayout(self)
        v_layout.addWidget(self.text)
        v_layout.addWidget(self.btn_return)
        self.setLayout(v_layout)
        self.setWindowTitle('Opened Text')

        self.btn_return.clicked.connect(self.closeAndReturn)

    def closeAndReturn(self):
        self.close()
        self.parent().show()

class Window(QMainWindow):

    textChanged = QtCore.pyqtSignal(str)

    def __init__(self, *args):
        super(Window, self).__init__()

        self.setAttribute(QtCore.Qt.WA_DeleteOnClose)

        self.img = QLabel()
        self.load_file= QPushButton('Load')

        self.width = 400
        self.height = 150        

        self.init_ui()

    def init_ui(self):
        self.img.setPixmap(QtGui.QPixmap("someimage.png"))


        h_layout = QHBoxLayout()
        v_layout = QVBoxLayout()
        h_final = QHBoxLayout()

        h_layout.addWidget(self.img)

        v_layout.addWidget(self.load_file)

        h_final.addLayout(h_layout)
        h_final.addLayout(v_layout)

        self.load_file.clicked.connect(self.loadafile)

        self.setLayout(h_final)
        self.setWindowTitle('Main Window')
        self.setGeometry(600,150,self.width,self.height)

    @QtCore.pyqtSlot()
    def loadafile(self):
        filename = QFileDialog.getOpenFileName(self, 'Open File', os.getenv('HOME'))
        with open(filename[0], 'r') as f:
            file_text = f.read()
            self.textChanged.emit(file_text)

        self.hide()
        self.dialog_02 = SecondWindow(self)
        self.dialog_02.show()

def main():
    app = QApplication(sys.argv)
    main = Window()
    s = SecondWindow(main)
    main.textChanged.connect(s.text.append)
    main.show()



    sys.exit(app.exec_())

if __name__ == '__main__':
    main()

1 Ответ

1 голос
/ 11 марта 2019

Вы объединяете много классов: что произойдет, если в данный момент SecondWindow не имеет родителя?Что ж, у вашего кода будут проблемы, и вам придется его сильно модифицировать, чтобы он работал правильно.Итак, сначала нужно спроектировать поведение каждого класса, например, SecondWindow должен предупредить другие окна, что по нему щелкнули, у него должен быть метод, который обновляет текст.Аналогично, Window должен уведомить о наличии нового текста.

С другой стороны, QMainWindow уже имеет предопределенный макет , поэтому вы должны создать центральный виджет, в который вы помещаете другие виджеты.

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

class SecondWindow(QtWidgets.QWidget):
    closed = QtCore.pyqtSignal()

    def __init__(self, parent=None):
        super(SecondWindow, self).__init__(parent, QtCore.Qt.Window)
        self.text = QtWidgets.QTextEdit()
        self.btn_return= QtWidgets.QPushButton("Return")
        self.init_ui()

    def init_ui(self):
        v_layout = QtWidgets.QVBoxLayout(self)
        v_layout.addWidget(self.text)
        v_layout.addWidget(self.btn_return)
        self.setWindowTitle('Opened Text')
        self.btn_return.clicked.connect(self.close)
        self.btn_return.clicked.connect(self.closed)

    @QtCore.pyqtSlot(str)
    def update_text(self, text):
        self.text.setText(text)
        self.show()

class Window(QtWidgets.QMainWindow):
    textChanged = QtCore.pyqtSignal(str)

    def __init__(self, *args):
        super(Window, self).__init__()
        self.img = QtWidgets.QLabel()
        self.load_file= QtWidgets.QPushButton('Load')
        self.width = 400
        self.height = 150        
        self.init_ui()

    def init_ui(self):
        self.img.setPixmap(QtGui.QPixmap("someimage.png"))
        self.load_file.clicked.connect(self.loadafile)
        central_widget = QtWidgets.QWidget()
        self.setCentralWidget(central_widget)
        h_layout = QtWidgets.QHBoxLayout(central_widget)
        h_layout.addWidget(self.img)
        h_layout.addWidget(self.load_file)
        self.setWindowTitle('Main Window')
        self.setGeometry(600,150,self.width,self.height)

    @QtCore.pyqtSlot()
    def loadafile(self):
        filename, _ = QtWidgets.QFileDialog.getOpenFileName(self, 'Open File', os.getenv('HOME'))
        if filename:
            with open(filename, 'r') as f:
                file_text = f.read()
                self.textChanged.emit(file_text)
                self.close()

def main():
    app = QtWidgets.QApplication(sys.argv)
    main = Window()
    s = SecondWindow()
    main.textChanged.connect(s.update_text)
    s.closed.connect(main.show)
    main.show()
    sys.exit(app.exec_())

if __name__ == '__main__':
    main()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...