質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.49%

  • Python 3.x

    6432questions

    Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

親画面から子画面の表示イベントはできますが、子画面の閉じるイベントができない

解決済

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 154

yumekichi

score 5

python 初心者です。
半年前から本やインターネットで勉強し断片的ですが
希望する動作を確認できるまでになったところです。

今度は断片的なソフトを集めて総合アプリを考えており、主メニュー画面から
各ソフトを起動してみたいと考えGUIで、wxpython を勉強中ですが問題にぶつかりました。

【発生している問題】
A画面で数字を入力するのに、付箋画面Bを立ち上げ内容を確認できるようにしたいのですが

A画面から B画面 立ち上げるイベント処理 はうまくいきますが
A画面から B画面を閉じるイベント処理ができません。

*・B画面のパラメータからは閉じることができます。
*・A画面を閉じるとB画面も閉じます。

【 該当のソースコードをテスト版で作りました】

!/usr/bin/env python

-*- coding:utf-8 -*-

import wx

class ChildFrame(wx.Frame):
def init(self,parent):
wx.Frame.init(self,parent,wx.ID_ANY,"child frame",pos=(100,100))

pane2 = wx.Panel(self)
self.exitBtn = wx.Button(pane2,label="閉じる",pos=(100,10))
self.Bind(wx.EVT_BUTTON,self.exit2,self.exitBtn)

def exit2(self,event):
self.Close(True)   #ここでは子の画面は閉じる

class MyWindow(wx.Frame):
def init(self,parent,id):
wx.Frame.init(self,parent,wx.ID_ANY,"main frame")
panel = wx.Panel(self)
self.showChildBtn = wx.Button(panel,label="show child",pos=(10,10))
self.exitBtn = wx.Button(panel,label="exit",pos=(100,10))
self.Bind(wx.EVT_BUTTON,self.showChild,self.showChildBtn)
self.Bind(wx.EVT_BUTTON,self.exit,self.exitBtn)

def showChild(self,event):
childFrame = ChildFrame(self)
childID = childFrame.Show()  #子の画面が開く
return True

def exit(self,event ):
childFrame = ChildFrame(self)
childFrame.Close(True)     #子の画面が閉じない、エラーコメントもない

if name == 'main':
app = wx.PySimpleApp()
frame = MyWindow(parent=None,id=-1)
frame.Show()
app.MainLoop()

本当はB画面ソフトはモジュール化で別に置いておきたいですが、まだそのレベルでないようです。
できればモジュール化の場合には注意する点が有ればご指導お願いします。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

0

◇原因
MyWindowクラスの以下の処理は今開いている子画面とは別の新しい子の画面が作られるためです。

   def exit(self, event ):
      #今開いている子画面以外に新しく子画面を作る
      childFrame = ChildFrame(self)
      # 上記で作った子画面を閉じる
      childFrame.Close(True)
      # ※CloseではなくShowを試してみてください。子画面が2個開くのが確認できるかと
      # 同じ位置に子画面が重なっているのでウィンドウを少しずらしてみてくださいな。
      #childFrame.Show() 

◇解決方法
親子関係がある画面で親から子をどうしても閉じたい場合は
親の初期処理で子画面を作成して子画面の表示/非表示を切り替える形が良いと思います。

# -*- coding: utf-8 -*-
import wx

class ChildFrame(wx.Frame):
    def __init__(self,parent):
        wx.Frame.__init__(self,parent,wx.ID_ANY,"child frame",pos=(100,100))

        pane2 = wx.Panel(self)
        self.exitBtn = wx.Button(pane2,label="閉じる",pos=(100,10))
        self.Bind(wx.EVT_BUTTON,self.exit2,self.exitBtn)

    def exit2(self,event):
        # 画面を閉じるではなく非表示に
        self.Show(False)

class MyWindow(wx.Frame):

    def __init__(self, parent, id):
        wx.Frame.__init__(self,parent,wx.ID_ANY,"main frame")
        panel = wx.Panel(self)
        self.showChildBtn = wx.Button(panel,label="show child",pos=(10,10))
        self.exitBtn = wx.Button(panel,label="exit",pos=(100,10))
        self.Bind(wx.EVT_BUTTON,self.showChild,self.showChildBtn)
        self.Bind(wx.EVT_BUTTON,self.exit,self.exitBtn)
        # 子画面を生成する
        self.childFrame = ChildFrame(self)

    def showChild(self,event):
        self.childFrame.Show()
        return True

    def exit(self, event):
        self.childFrame.exit2(None)


if __name__ == '__main__':
    app = wx.PySimpleApp()
    frame = MyWindow(parent=None,id=-1)
    frame.Show()
    app.MainLoop()

◇モジュール化の注意点
実際の家を建てる時、内装も大事ですが基礎工事(土台)も大事ですよね。
モジュールはアプリケーションを構成するための土台です。よって同じような事が言えます。
基礎設計が大事。

大枠でもいいので、紙やメモ帳などに親/子関係と相手に渡す情報/相手から受け取る情報を記述されるのをお勧め致します。

1,モジュールレベルの単体テストを行う。
if __name__ == '__main__':を使ってそのモジュール単体でテストできるようにした方がいいと思います。

2,重要な処理/内容ははログ情報をできるだけ残す。

logging — Python 用ロギング機能が使えます

3,モジュール間の階層構造を意識して作成する。


◇最後に質問文のコードの書き方について
Pythonはインデントが重要な言語です。
ソースコードをそのまま転記するとインデント情報が消えてしまいます。
以下の画像を参考に質問文のコードは記載してくださいな。
コードの書き方

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/07/22 19:10

    回答有難うございます。 正直3~4日悩んでネットを調べていましたが適切な回答がなく
    壁にぶち当たっていたところでした。

    もう少し基本を勉強しないといけないようですね。反省します。
    Tagインデントの件、送信した後気づきました。今後注意します。
    今後もよろしくお願いします。

    キャンセル

  • 2018/07/22 19:16

    >yumekichiさんへ
    解決してよかったです。
    こういう事象はネットのサンプルコードでは考慮されていないことが多いので、ハマりやすいポイントでしょうか。どちらかというとteratailとかの過去質問を検索するとヒットしやすいかと。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.49%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • Python 3.x

    6432questions

    Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。