نوافذ متعددة في PyQt4
-
22-07-2019 - |
سؤال
لدي برنامج PyQt يستخدم لتصور بعض كائنات بايثون.أرغب في عرض كائنات متعددة، كل منها في نافذتها الخاصة.
ما هي أفضل طريقة لتحقيق تطبيقات النوافذ المتعددة في PyQt4؟
حاليا لدي ما يلي:
from PyQt4 import QtGui
class MainWindow(QtGui.QMainWindow):
windowList = []
def __init__(self, animal):
pass
def addwindow(self, animal)
win = MainWindow(animal)
windowList.append(win)
if __name__=="__main__":
import sys
app = QtGui.QApplication(sys.argv)
win = QMainWindow(dog)
win.addWindow(fish)
win.addWindow(cat)
app.exec_()
ومع ذلك، فإن هذا الأسلوب غير مرضٍ، حيث أواجه مشكلات عندما أحاول استبعاد جزء MultiWindows في فئته الخاصة.على سبيل المثال:
class MultiWindows(QtGui.QMainWindow):
windowList = []
def __init__(self, param):
raise NotImplementedError()
def addwindow(self, param)
win = MainWindow(param) # How to call the initializer of the subclass from here?
windowList.append(win)
class PlanetApp(MultiWindows):
def __init__(self, planet):
pass
class AnimalApp(MultiWindows):
def __init__(self, planet):
pass
if __name__=="__main__":
import sys
app = QtGui.QApplication(sys.argv)
win = PlanetApp(mercury)
win.addWindow(venus)
win.addWindow(jupiter)
app.exec_()
سوف يستدعي الكود أعلاه مُهيئ فئة MainWindow، بدلاً من مُهيئ الفئة الفرعية المناسبة، وبالتالي سيطرح استثناءً.
كيف يمكنني استدعاء مُهيئ الفئة الفرعية؟هل هناك طريقة أكثر أناقة للقيام بذلك؟
المحلول
لماذا لا تستخدم مربعات الحوار؟في Qt لا تحتاج إلى استخدام النافذة الرئيسية إلا إذا كنت تريد استخدام الموانئ وما إلى ذلك.استخدام مربعات الحوار سيكون له نفس التأثير.
أستطيع أيضًا أن أرى مشكلة في منطقك فيما يتعلق بحقيقة أنك تريد أن تقوم صفك المتميز باستدعاء المُنشئ لأطفاله، والذي يمكن أن يكون بالطبع من أي نوع.أنصحك بإعادة كتابته على النحو التالي:
class MultiWindows(QtGui.QMainWindow):
def __init__(self, param):
self.__windows = []
def addwindow(self, window):
self.__windows.append(window)
def show():
for current_child_window in self.__windows:
current_child_window.exec_() # probably show will do the same trick
class PlanetApp(QtGui.QDialog):
def __init__(self, parent, planet):
QtGui.QDialog.__init__(self, parent)
# do cool stuff here
class AnimalApp(QtGui.QDialog):
def __init__(self, parent, animal):
QtGui.QDialog.__init__(self, parent)
# do cool stuff here
if __name__=="__main__":
import sys # really need this here??
app = QtGui.QApplication(sys.argv)
jupiter = PlanetApp(None, "jupiter")
venus = PlanetApp(None, "venus")
windows = MultiWindows()
windows.addWindow(jupiter)
windows.addWindow(venus)
windows.show()
app.exec_()
إنها ليست فكرة جيدة أن تتوقع أن تعرف الفئة الفائقة المعلمة التي سيتم استخدامها في فيه من فئاتها الفرعية نظرًا لأنه من الصعب حقًا التأكد من أن كل المُنشئ سيكون هو نفسه (ربما يأخذ مربع حوار/نافذة الحيوان معلمات مختلفة).
نأمل أن يساعد.
نصائح أخرى
في أجل الرجوع إلى فئة فرعية أن يرث الطبقة السوبر من داخل عظمى من الدرجة، وأنا أستخدمه self.__class__()
، بحيث يقرأ الدرجة MultiWindows الآن:
class MultiWindows(QtGui.QMainWindow):
windowList = []
def __init__(self, param):
raise NotImplementedError()
def addwindow(self, param)
win = self.__class__(param)
windowList.append(win)