48399


Pyqt5でメインウィンドウからサブウィンドウを閉じたいです。そこで次のようなコードを書いてみました。

[code]

    import sys
    from PyQt5 import*
    from PyQt5.QtWidgets import *
    from PyQt5.QtGui import *
    from PyQt5.QtCore import *
    from PyQt5 import QtGui,QtCore, QtWidgets
    
    
    class Second:
        def __init__(self, parent=None):
            self.w = QDialog(parent)
            self.parent = parent
            #Setting a title, locating and sizing the window
            self.title = 'My Second Window'
            self.left = 200
            self.top = 200
            self.width = 500
            self.height = 500
            self.w.setWindowTitle(self.title)
            self.w.setGeometry(self.left, self.top, self.width, self.height)
            self.pushButton = QtWidgets.QPushButton("Close Me")
            self.pushButton.clicked.connect(self.on_pushButton_clicked)
            #self.pushButton.move(120,120)
            layout1=QHBoxLayout()
            layout1.addWidget(self.pushButton)
            self.w.setLayout(layout1)
    
    
        def on_pushButton_clicked(self):
            self.w.close()
    
    
        def show(self):
            self.w.exec_()
    
    
    class First(QtWidgets.QWidget):
        def __init__(self, parent=None):
            super(First, self).__init__(parent)
            self.title = 'My First Window'
            self.left = 100
            self.top = 100
            self.width = 500
            self.height = 500
            self.setWindowTitle(self.title)
            self.setGeometry(self.left, self.top, self.width, self.height)
            self.pushButton = QtWidgets.QPushButton("Open Me", self)
            self.pushButton2 = QtWidgets.QPushButton("close", self)
            #self.pushButton.move(120,120)
            self.pushButton.clicked.connect(self.on_pushButton_clicked) 
            self.pushButton2.clicked.connect(self.on_pushButton2_clicked) 
    
    
            layout1=QHBoxLayout()
            layout1.addWidget(self.pushButton)
            layout1.addWidget(self.pushButton2)
    
            self.setLayout(layout1)
    
        def on_pushButton_clicked(self):
            self.newWindow = Second(self)
            self.newWindow.show()
    
        def on_pushButton2_clicked(self):
            self.newWindow = Second(self)
            self.newWindow.close()
    
    if __name__ == '__main__':
        app = QtWidgets.QApplication(sys.argv)
        main = First()
        main.show()
        sys.exit(app.exec_())
    
[/code]

これによって下図左のようなGUIが作成されます。  
[![画像](https://i.stack.imgur.com/0k7d8.png)](https://i.stack.imgur.com/0k7d8.png)  
ここで、「Open
Me」のボタンを押すと右側のようなサブウィンドウが開きます。ここで、メインウィンドウの「close」ボタンを押したときにサブウィンドウが閉じるようにしたいです。しかし今のままではサブウィンドウを開いている間はメインウィンドウをいじることは出来ません。

そこで次に下のようなコードを書きました。

[code]

    import sys
    from PyQt5 import QtCore, QtWidgets
    from PyQt5.QtWidgets import *
    
    class Second(QtWidgets.QMainWindow):
        def __init__(self, parent=None):
            super(Second, self).__init__(parent)
            #Setting a title, locating and sizing the window
            self.title = 'My Second Window'
            self.left = 200
            self.top = 200
            self.width = 500
            self.height = 500
            self.setWindowTitle(self.title)
            self.setGeometry(self.left, self.top, self.width, self.height)
            self.pushButton = QtWidgets.QPushButton("Close Me", self)
            self.pushButton.clicked.connect(self.on_pushButton_clicked)
            self.pushButton.move(120,120)
    
        def on_pushButton_clicked(self):
            self.close()
    
    class First(QtWidgets.QMainWindow):
        def __init__(self, parent=None):
            super(First, self).__init__(parent)
            self.title = 'My First Window'
            self.left = 100
            self.top = 100
            self.width = 500
            self.height = 500
            self.setWindowTitle(self.title)
            self.setGeometry(self.left, self.top, self.width, self.height)
            self.pushButton = QtWidgets.QPushButton("Open Me", self)
            self.pushButton.move(120,120)
            self.pushButton.clicked.connect(self.on_pushButton_clicked)
            self.pushButton2 = QtWidgets.QPushButton("Close Me", self)
            self.pushButton2.move(120,150)
            self.pushButton2.clicked.connect(self.on_pushButton2_clicked) 
            self.newWindow = Second(self)
    
        def on_pushButton_clicked(self):
            self.newWindow.show()
    
        def on_pushButton2_clicked(self):
            self.newWindow.close()
    
    if __name__ == '__main__':
        app = QtWidgets.QApplication(sys.argv)
        main = First()
        main.show()
        sys.exit(app.exec_())
    
[/code]

これによりメインウィンドウからでもサブウィンドウを閉じることが出来るようになりました。しかし、ボタンの配置をレイアウトで書こうと次のように書き直しました。

[code]

    import sys
    from PyQt5 import*
    from PyQt5.QtWidgets import *
    from PyQt5.QtGui import *
    from PyQt5.QtCore import *
    from PyQt5 import QtGui,QtCore, QtWidgets
    
    
    class Second(QtWidgets.QWidget):
        def __init__(self, parent=None):
            super(Second, self).__init__(parent)
            #Setting a title, locating and sizing the window
            self.title = 'My Second Window'
            self.left = 200
            self.top = 200
            self.width = 500
            self.height = 500
            self.setWindowTitle(self.title)
            self.setGeometry(self.left, self.top, self.width, self.height)
            self.pushButton = QtWidgets.QPushButton("Close Me",self)
            self.pushButton.clicked.connect(self.on_pushButton_clicked)
            #self.pushButton.move(120,120)
            layout1=QHBoxLayout()
            layout1.addWidget(self.pushButton)
            self.setLayout(layout1)
    
    
        def on_pushButton_clicked(self):
            self.close()
    
    class First(QtWidgets.QWidget):
        def __init__(self, parent=None):
            super(First, self).__init__(parent)
            self.title = 'My First Window'
            self.left = 100
            self.top = 100
            self.width = 500
            self.height = 500
            self.setWindowTitle(self.title)
            self.setGeometry(self.left, self.top, self.width, self.height)
            self.pushButton = QtWidgets.QPushButton("Open Me", self)
            self.pushButton2 = QtWidgets.QPushButton("close", self)
            #self.pushButton.move(120,120)
            self.pushButton.clicked.connect(self.on_pushButton_clicked) 
            self.pushButton2.clicked.connect(self.on_pushButton2_clicked) 
            self.newWindow = Second(self)
    
            layout1=QHBoxLayout()
            layout1.addWidget(self.pushButton)
            layout1.addWidget(self.pushButton2)
    
            self.setLayout(layout1)
    
        def on_pushButton_clicked(self):
            #self.newWindow = Second(self)
            self.newWindow.show()
    
        def on_pushButton2_clicked(self):
            #self.newWindow = Second(self)
            self.newWindow.close()
    
    if __name__ == '__main__':
        app = QtWidgets.QApplication(sys.argv)
        main = First()
        main.show()
        sys.exit(app.exec_())
    
[/code]

すると、下図のようにメインウィンドウとサブウィンドウが一緒に表示されました。  
[![画像2](https://i.stack.imgur.com/tqYPK.png)](https://i.stack.imgur.com/tqYPK.png)  
ボタンをレイアウト形式で配置しつつ、サブウィンドウを表示しながらもメインウィンドウを操作できるようにするにはいったいどうしたらよいのでしょうか。


CC BY-SA 4.0
2018-09-14T12:33:43.013
48398
2018-09-14T12:59:40.023
26529
question
python3 pyqt5
Pyqt5でサブウィンドウを開きつつメインウィンドウを操作したい


`First`の初期化コード(`__init__`)内で、`Second`を生成する際に`self`(=`First`のオブジェクト)を指定しているためと思います。

[code]

        self.newWindow = Second(self)
    
[/code]

`self`を指定しないことで事象は解決すると思います。

[code]

        self.newWindow = Second()
    
[/code]

＃`self`を指定すると、`Second`オブジェクト(`QWidget`)は`First`オブジェクト(`QWidget`)の子と認識されるため、`First`オブジェクトの内部に描画されていると思います。  
`QMainWindow`は例外的にトップレベルウインドウになるように実装されているため、別々のウインドウになっていたと思います。

＃蛇足ながら、最初のコード例は、`QDialog`でモーダルダイアログを表示させたため、親画面に制御が映らなかったものと思います。


CC BY-SA 4.0
2018-09-14T12:59:40.023
48399
2018-09-14T12:59:40.023
20098
48398
answer