2016-11-04 15 views
3

前のquestionを参照すると、私のアプリケーションで参照を保持するための助けが必要です。Qt - Pythonでウィジェットの参照を保持する

最初に私のコードからスニペット。

from PyQt4 import QtGui 
import os, os.path 
import sys 

class mainWindowHandler(): 

    equationEditor = [] 
    _listview = None 
    _window = None  

    def __init__(self): 
     return 

    def showAddEquation(self): 
     """Creates a new instance of the dynamic editor for adding an equation""" 

     #create a horizontal split layout 
     window = QtGui.QWidget() 
     layout = QtGui.QHBoxLayout() 

     current = len(self.equationEditor) - 1 
     de = QtGui.QPushButton(str(current)) 
     self.equationEditor.append(de) 

     de.clicked.connect(self.clicked)      

     #fill list view with items from equation collection 
     listview = QtGui.QListWidget() 
     for equation in self.equationEditor: 
      item = QtGui.QListWidgetItem() 
      item.setText(equation.text()) 
      listview.addItem(item)    
     layout.addWidget(listview) 
     layout.addWidget(de) 

     window.setWindowTitle("Equation {}".format(str(current)) 
     window.setLayout(layout) 

     self._window = window 
     self._listview = listview 
     window.show() 

     return window 

    def clicked(self): 
     """Method for handling the button events in the solver settings\n 
     signal = the button hit\n"""   
     return self.showAddEquation() 

if __name__ == "__main__": 
    path = os.path.dirname(os.path.abspath(__file__)) 
    app = QtGui.QApplication(sys.argv) 
    ewh = mainWindowHandler() 
    window = ewh.showAddEquation() 
    sys.exit(app.exec_()) 

(後に)特定の設定の操作を可能にするウィンドウを作成するアプリケーション - QPushButtonで表される私のコード例では。これらの設定は後でtxtファイルに書き込まれますが、それまではウィジェットの形式で保存されます。ウィジェットをコレクションに追加してそこから呼び出すだけです。これはPythonレベルでうまくいきます。

今、ウィンドウの内側からウィンドウの新しいインスタンスを作成するボタンがあります。それも動作します。しかし、3つ目のインスタンスまで。その時点で私はQtレベルの私のQPushButtonへの参照を失いました。私のコレクション(equationEditor)からボタンを取得しようとしたとき、私は

wrapped C/C++ object of type `QPushButton` has been deleted 

エラーが発生します。 Pythonではまだそれらが存在しますが、明らかに対応するQtオブジェクトはどこかで参照を誤ってしまったために破壊されます。

誰かがより良い解決策を示したり、私が参照を保持する方法を指摘できますか? おかげで...


編集:私は詳細に少しより多くの機能を説明しようとするいくつかの混乱があるように思えたよう

プログラムが起動し、QListViewQPushButtonが「1」のウィンドウ「式1」が作成されます。リストビューには、利用可能なすべてのQPushButtonが表示されます(開始時に1項目のみ)。私の実際のプログラムではQPushButtonQWidgetで、一部のテキストフィールドとQPushButtonです。

ユーザーが「1」をクリックすると、「1」ボタンが消え、「1」の位置に「2」という名前の新しいインスタンスQPushButtonが表示されます。さらに、リストビューは2つの項目「1」と「2」を保持するはずであり、ウィンドウのタイトルは「式2」でなければなりません。それが新しいウィンドウであるか、以前と同じ新しいコンテンツでは関連性がありません。両方の変種は大丈夫でしょう。前者は現時点で実装されている方法です。表示は一度に1つのウィンドウで行う必要があります。

QPushButtonのすべてのインスタンスは、小さなリスト(equationEditorと呼ばれます)で収集してメモリに保持する必要があります。私の実際のプログラムでは、これは変更を一時ファイルに書き込まずにウィジェット内のすべての変更を保存するために使用されます。

その後、ユーザが選択した場合、項目「1」、現在可視QPushButtonが(コレクションequationEditorから)QPushButton「1」に置き換えなければならないQListViewまたは彼は2番目の項目を選択した場合QPushButton「2」べき示される。

なぜですか? 後で使用されるウィジェットには、多くの編集可能なデータが含まれています。ユーザーはいつでもその情報を編集できるので、すべてのデータを再度再投入するのではなく、ウィジェットを表示せずにウィジェットをメモリに保持する方が簡単です。ユーザがQListViewで1つを選択するとすぐに、ウィジェット内のデータを再び編集できるように、対応するウィジェットをウィンドウに表示する必要があります。

答えて

1

正確に何をしようとしているのかを理解することはかなり難しいです。あなたのコードを見ると、なぜ失敗する前に2回働いているのだろうと思います。

Btw。私はちょうど、Scholliiによって与えられたquite accurate description of why it's failingが前の投稿にあることを見た。

とにかく、あなたは方程式ウィンドウのための新しいクラスを作るべきだと思う。メインクラスでは、equationEditorリストの開いているすべてのウィンドウを追跡できます。また、作成された新しいウィンドウに他の開いているウィンドウの値を追加することもできます。ここで

は、それは私が私の問題を解決した最初の答えで与えられたアプローチを理解した上で、だから、

from PyQt4 import QtGui 
import os, os.path 
import sys 

class ShowAddEquation(QtGui.QWidget): 
    """Creates a new instance of the dynamic editor for adding an equation""" 
    def __init__(self,parent=None): 
     super(ShowAddEquation, self).__init__(parent=parent) 
     #create a horizontal split layout 
     layout = QtGui.QHBoxLayout() 

     self.current = 0 
     self.de = QtGui.QPushButton(str(self.current)) 
     self.listview = QtGui.QListWidget() 

     layout.addWidget(self.listview) 
     layout.addWidget(self.de) 

     self.setWindowTitle("Equation Editor") 
     self.setLayout(layout) 

     self.show() 

    def setCurrent(self, current): 
     self.current=current 
     self.de.setText(str(self.current)) 



class mainWindowHandler(): 

    equationEditor = [] 

    def __init__(self): 
     return 

    def clicked(self): 
     se = ShowAddEquation() 
     self.equationEditor.append(se) 
     se.de.clicked.connect(self.clicked) 
     current = len(self.equationEditor) - 1 
     se.setCurrent(current) 
     for equation in self.equationEditor: 
      item = QtGui.QListWidgetItem() 
      item.setText(str(equation.current)) 
      se.listview.addItem(item) 


if __name__ == "__main__": 
    path = os.path.dirname(os.path.abspath(__file__)) 
    app = QtGui.QApplication(sys.argv) 
    ewh = mainWindowHandler() 
    ewh.clicked() 
    sys.exit(app.exec_()) 
+0

あなたのコード例のおかげで。私はそれを見ます。トリッキーな部分は、リストビュー内の対応する項目が選択されたときに、メモリからウィンドウを呼び出すことになります。 – RaJa

+0

今のように、listviewの数字は、ちょうど 'equationEditor'リスト内の対応する' ShowAddEquation'インスタンスのインデックスです。だから問題はないはずです。 – ImportanceOfBeingErnest

+0

これは正しいです。リストビューでアイテムが選択されると、現在表示されているプッシュボタンが非表示になり、アイテムにリンクされているプッシュボタンが現在のウィンドウに表示されます。そのため、実際には 'ShowAddEquation'ではなく' equationEditor'にPushButtonを追加しています。最後に、アイテムを選択するときに右の視界が変化するウィンドウ(PushButton)が表示され、ユーザーがボタンを押したときに再作成されるウィンドウが表示されます。 – RaJa

0

のようになります方法です。ここに作業コード

# -*- coding: utf-8 -*- 
""" 
Created on Sat Sep 3 14:31:15 2016 

""" 

from PyQt4 import QtGui 
from PyQt4 import QtCore 

import os, os.path 
import sys 

class mainWindowHandler(): 

    equationEditor = [] 
    _listview = None 
    _window = None  

    def __init__(self): 
     return 

    def showAddEquation(self): 
     """Creates a new instance of the dynamic editor for adding an equation""" 

     #create a horizontal split layout 
     self._window = QtGui.QWidget() 
     layout = QtGui.QHBoxLayout() 
     self._listview = QtGui.QListWidget() 
     layout.addWidget(self._listview) 

     self._listview.clicked[QtCore.QModelIndex].connect(self.changed)   

     self._window.setLayout(layout)  
     #populate the right side of the layout with a button 
     self.clicked()   

     self._window.show() 

     return self._window 

    def clicked(self): 
     """Make a new button instance and add it to the window and the collection"""   
     window = self._window 
     layout = window.layout() 

     current = len(self.equationEditor) - 1 
     de = QtGui.QPushButton(str(current)) 
     self.equationEditor.append(de) 

     de.clicked.connect(self.clicked)  
     #close the currently shown button 
     item = layout.takeAt(1) 
     if item is not None: 
      item.widget().close()     
     layout.addWidget(de) 

     #fill list view with items from material collection 
     item = QtGui.QListWidgetItem() 
     item.setText(de.text()) 
     self._listview.addItem(item)  
     self._window.setWindowTitle("Equation Editor {}".format(str(current)))   

    def changed(self, index): 
     """hide the object on the right side of the layout and show the button at position index in the collection""" 
     layout = self._window.layout() 
     item = layout.takeAt(1) 
     item.widget().close() 
     # insert the selected button from the collection 
     de = self.equationEditor[index.row()] 
     layout.insertWidget(1, de)   
     self._window.setWindowTitle("Equation Editor {}".format(str(index.row() - 1)))   
     de.show()   


if __name__ == "__main__": 
    path = os.path.dirname(os.path.abspath(__file__)) 
    app = QtGui.QApplication(sys.argv) 
    ewh = mainWindowHandler() 
    window = ewh.showAddEquation() 
    sys.exit(app.exec_()) 
+0

私は今あなたが欲しいものを見ます。私はこの構造が保持できるとは確信していませんが、より現実的な情報をButtonに保存する必要がある場合は、それに満足すればうまくいきます。 – ImportanceOfBeingErnest

関連する問題