Welches Unterfenster ist gerade aktiv?

Python und das Qt-Toolkit, erstellen von GUIs mittels des Qt-Designers.
Antworten
Benutzeravatar
Sophus
User
Beiträge: 1109
Registriert: Freitag 25. April 2014, 12:46
Wohnort: Osnabrück

Hallo Leute,

im nachfolgenden, ausführbaren Quelltext werden Unterfenster in das MDI-Konzept geladen. Es klappt alles wunderbar. Was möchte ich? Ihr seht die Custom_Window()-Klasse, die als Unterfenster fungieren sollen. Innerhalb dieser eben genannten Klasse seht ihr eine überschriebene changeEvent()-Methode. Ich möchte auf diesem Wege herausfinden, welches der folgende Fenster gerade aktiv ist. Wenn ihr diesen Quelltext auf eurem Rechner ausführt, dann öffnet mal von mir aus zwei oder drei Unterfenster, und wechselt von einem Unterfenster zu nächsten. Ich möchte, dass jedes dieser Fenster von sich aus mitteilen kann, ob es gerade aktive ist. Aber irgendwie will meine Vorgehensweise nicht klappen.

Habt ihr eine Idee?

Code: Alles auswählen

import sys
from PyQt4.QtCore import *
from PyQt4.QtGui import *

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

      # print here in this class, that itself is currently active,
      # because this window is a subwindow, so its inherits from class
      # QMdiSubWindow(). I want this subwindow itself tell me
      # whether its activated or not. BUT I don't know how to
      # solve this idea.

   def changeEvent(self, event):

      print "event", event
      print "type", type(self.parent())
      print "Status", self.parent().isActiveWindow()

      if event.type() == QEvent.WindowActivate:
         if self.parent().isActiveWindow():
            print "is currently active."
         else: print "I am passive"

class MainWindow(QMainWindow) :
   count = 0

   def __init__(self, parent = None) :
      super(MainWindow, self) .__init__(parent)
      self.mdi = QMdiArea()
      self.setCentralWidget(self.mdi)
      bar = self.menuBar()

      file = bar.addMenu("File")
      file.addAction("New")
      file.addAction("cascade")
      file.addAction("Tiled")
      file.triggered[QAction].connect(self.windowaction)
      self.setWindowTitle("MDI demo")

   def windowaction(self, q) :
       custom_window = Custom_Window()
       print "triggered"

       if q.text() == "New" :
           MainWindow.count = MainWindow.count+1
           sub = QMdiSubWindow()
           sub.setWidget(Custom_Window() )
           sub.setWindowTitle("subwindow"+str(MainWindow.count) )
           self.mdi.addSubWindow(sub)
           sub.show()

       if q.text() == "cascade" :
           self.mdi.cascadeSubWindows()

       if q.text() == "Tiled" :
           self.mdi.tileSubWindows()

def main() :
   app = QApplication(sys.argv)
   ex = MainWindow()
   ex.show()
   sys.exit(app.exec_() )

if __name__ == '__main__':
   main()
Benutzeravatar
Sophus
User
Beiträge: 1109
Registriert: Freitag 25. April 2014, 12:46
Wohnort: Osnabrück

Nach langem Suchen und Wühlen bin ich auf eine mögliche Lösung gestoßen. Allerdings empfinde ich die Lösung etwas "unbeholen". Dazu gleich mehr.

Damit etwas mehr Sinn ergibt, habe ich zum Unterfenster ein QPushButton()-Objekt hinzugefügt. Was habe ich getan? Ich habe in der Custom_Window()-Klasse die handle_activation_change()-Methode hinzugefügt. Der Methode wird das subwindow-Argument hinzugefügt. Darüber erhält die Methode das QMdiSubWindow()-Objekt. Beim entsprechenden Vergleich werden die Schaltflächen deaktiviert, sobald ein Unterfenster passiv ist. Andersrum, wenn ein Fenster aktiv wird, wird die Schaltfläche aktiviert.

Was mir Sorgen bereitet: Mit einem Blick in die windowaction()-Methode innerhalb der MainWindow() -Klasse wird die subWindowActivated()-Methode mit der handle_activation_change()-Methode aus der Custom_Window()-Klasse verbunden. Frage: Ist hier nicht zuviel Implementierungsdetail? Denn die MDI-Ebene weißt zuviel über die Unterfenster. Sollte es der MDI-Ebene nicht interessieren, welche Funktionen das Unterfenster hat? Oder kann man das so gelten lassen?

Code: Alles auswählen

import sys
from PyQt4.QtCore import *
from PyQt4.QtGui import *

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

      self.edit = QLineEdit(self)
      self.push_button = QPushButton("Click here", self)
      layout = QVBoxLayout(self)
      layout.addWidget(self.edit)
      layout.addWidget(self.push_button)

   def handle_activation_change(self, subwindow):
      if subwindow is self.parent():
         self.push_button.setEnabled(True)
      else:
         self.push_button.setEnabled(False)

class MainWindow(QMainWindow) :
   count = 0
	
   def __init__(self, parent = None) :
      super(MainWindow, self) .__init__(parent)
      self.mdi = QMdiArea()
      self.setCentralWidget(self.mdi)
      bar = self.menuBar()
	
      file = bar.addMenu("File")
      file.addAction("New")
      file.addAction("cascade")
      file.addAction("Tiled")
      file.triggered[QAction].connect(self.windowaction)
      self.setWindowTitle("MDI demo")
		
   def windowaction(self, q) :
       custom_window = Custom_Window()
       print "triggered"

       if q.text() == "New" :
          form = Custom_Window()
          MainWindow.count = MainWindow.count+1
          sub = QMdiSubWindow()
          sub.setWidget(form)
          sub.setWindowTitle("subwindow"+str(MainWindow.count) )
          self.mdi.addSubWindow(sub)
          form.show()

          self.mdi.subWindowActivated.connect(form.handle_activation_change)

          
       if q.text() == "cascade" :
           self.mdi.cascadeSubWindows()
                    
       if q.text() == "Tiled" :
           self.mdi.tileSubWindows()
		
def main() :
   app = QApplication(sys.argv)
   ex = MainWindow()
   ex.show()
   sys.exit(app.exec_() )
	
if __name__ == '__main__':
   main()
Antworten