2016-04-11 28 views
2

Ben ne olursa olsun aynı diyalog mesaj kutusu ile sunulan am böylece bir örnek genişletmek için çalışıyorum kendim için Alıştırma olarak burada Zetcode, PyQt5pyqt5 - Ben pyqt5 öğretici olsa çalışıyorum kapama/sonlandırma uygulama

bulundu uygulamayı kapatmak için kullanılan yöntemin:

  • başlık çubuğunda 'X' düğmesine tıklayarak (işler istendiği gibi) 'kaçış basarak 'Kapat' düğmesine (üreten nitelik hatası)
  • tıklayarak
  • 'anahtar (çalışır ama nasıl/neden olmadığından emin değilsiniz.

İletişim kutusu, sonunda sağlanan tam komut dosyası olan closeEvent yönteminde uygulanır.

İki sorunları yaşıyorum:

1. tıklayarak 'Kapat' düğmesine yerine sadece bırakma, ben mesaj kutusu iletişim de dahil olmak üzere closeEvent yöntemi çağırmak istiyorum.

Ben 'Close' düğme için örnek kod satırını yerini almıştır

:

btn.clicked.connect(QCoreApplication.instance().quit) 

Ve yerine zaten istediğim iletişim uygulayan closeEvent yöntemini çağırmak çalışıyorum:

btn.clicked.connect(self.closeEvent) 

Ancak, komut dosyasını çalıştırdığımda ve 'Kapat' düğmesini tıklatıp iletişim kutusundaki 'Kapat' seçeneğini belirledikten sonra aşağıdakileri elde ederim:

Yanlış yaptıklarını ve burada yapılması gerekenleri kimseye tavsiye edebilir mi?

2. Bir şekilde çıkış kutusu isabet ederken, ileti kutusu iletişim kutusu sunulur ve iyi çalışır.

Tamam, bunun işe yaradığını harika, ama nasıl ve neden CloseEvent yönteminde tanımlanan mesaj kutusu işlevselliği keyPressEvent yöntemi içinde denir bilmek istiyorum.

Tam komut aşağıdaki gibidir:

import sys 
from PyQt5.QtWidgets import (
    QApplication, QWidget, QToolTip, QPushButton, QMessageBox) 
from PyQt5.QtCore import QCoreApplication, Qt 


class Window(QWidget): 

    def __init__(self): 
     super().__init__() 

     self.initUI() 

    def initUI(self): 

     btn = QPushButton("Close", self) 
     btn.setToolTip("Close Application") 
     # btn.clicked.connect(QCoreApplication.instance().quit) 
     # instead of above button signal, try to call closeEvent method below 
     btn.clicked.connect(self.closeEvent) 

     btn.resize(btn.sizeHint()) 
     btn.move(410, 118) 
     self.setGeometry(30, 450, 500, 150) 
     self.setWindowTitle("Terminator") 
     self.show() 

    def closeEvent(self, event): 
     """Generate 'question' dialog on clicking 'X' button in title bar. 

     Reimplement the closeEvent() event handler to include a 'Question' 
     dialog with options on how to proceed - Save, Close, Cancel buttons 
     """ 
     reply = QMessageBox.question(
      self, "Message", 
      "Are you sure you want to quit? Any unsaved work will be lost.", 
      QMessageBox.Save | QMessageBox.Close | QMessageBox.Cancel, 
      QMessageBox.Save) 

     if reply == QMessageBox.Close: 
      event.accept() 
     else: 
      event.ignore() 

    def keyPressEvent(self, event): 
     """Close application from escape key. 

     results in QMessageBox dialog from closeEvent, good but how/why? 
     """ 
     if event.key() == Qt.Key_Escape: 
      self.close() 

if __name__ == '__main__': 

    app = QApplication(sys.argv) 
    w = Window() 
    sys.exit(app.exec_()) 

Umut birisi bana aydınlatmak zaman alabilir.

cevap

3

İkinci soru, ilk soruyu yanıtlar.

Yeniden yapılandırılan keyPressEvent yöntemi, yöntemini çağırır; bu, küçük birime QCloseEvent gönderir. Ardından, widget'ın closeEvent bu olayla argüman olarak çağrılacaktır.

Yani sadece widget'inin close() yuvasına için düğmeye bağlamak gerekir ve her şey beklendiği gibi çalışır:

btn.clicked.connect(self.close) 
+0

şimdi, teşekkürler. Bu arada, bu satırda onları nasıl sipariş ettiğime bakmadan iletişim penceremde düğme sırasını ayarlayamıyorum: 'QMessageBox.Save | QMessageBox.Close | QMessageBox.Cancel'. Ben onları otomatik olarak artan alfabetik sıraya göre ayarlar mı? – user3548783

+0

@ user3548783. Düğmeleri geçerli platform ve/veya widget stili için uygun olan her şekilde sipariş eden bir [QDialogButtonBox] (http://doc.qt.io/qt-5/qdialogbuttonbox.html#details) kullanılmalıdır. Farklı davranışlar istiyorsanız, her zaman kendi mesaj kutusu sınıfınızı oluşturabilirsiniz. – ekhumoro

0

aksine sizin özel düğme bir close event sadece bool geçmek görünmüyor X düğmesine basın. Bu yüzden bu egzersiz X düğmesi için çalışmalı, normal bir düğme değil. Her durumda, ilk soru için aynen bu şekilde destroy() ve pass yerine (bir accept ve ignore) kullanabilirsiniz: Qt varsayılan davranışlar Diyaloglar başka sahip olabilir (Widget bağlı olan ikinci soru için

import sys 
from PyQt5.QtWidgets import (
    QApplication, QWidget, QToolTip, QPushButton, QMessageBox) 
from PyQt5.QtCore import QCoreApplication, Qt 


class Window(QWidget): 

    def __init__(self): 
     super().__init__() 

     self.initUI() 

    def initUI(self): 

     btn = QPushButton("Close", self) 
     btn.setToolTip("Close Application") 
     # btn.clicked.connect(QCoreApplication.instance().quit) 
     # instead of above button signal, try to call closeEvent method below 
     btn.clicked.connect(self.closeEvent) 

     btn.resize(btn.sizeHint()) 
     btn.move(410, 118) 
     self.setGeometry(30, 450, 500, 150) 
     self.setWindowTitle("Terminator") 
     self.show() 

    def closeEvent(self, event): 
     """Generate 'question' dialog on clicking 'X' button in title bar. 

     Reimplement the closeEvent() event handler to include a 'Question' 
     dialog with options on how to proceed - Save, Close, Cancel buttons 
     """ 
     reply = QMessageBox.question(
      self, "Message", 
      "Are you sure you want to quit? Any unsaved work will be lost.", 
      QMessageBox.Save | QMessageBox.Close | QMessageBox.Cancel, 
      QMessageBox.Save) 

     if reply == QMessageBox.Close: 
      app.quit() 
     else: 
      pass 

    def keyPressEvent(self, event): 
     """Close application from escape key. 

     results in QMessageBox dialog from closeEvent, good but how/why? 
     """ 
     if event.key() == Qt.Key_Escape: 
      self.close() 

if __name__ == '__main__': 

    app = QApplication(sys.argv) 
    w = Window() 
    sys.exit(app.exec_()) 

, Mesaj İletişim Kutunuz sadece görmek için açıkken Esc tuşuna basmayı deneyin). Eğer Esc davranışı geçersiz gerekiyor olduğunda bunu deneyebilirsiniz:

def keyPressEvent(self, event): 
    if event.key() == QtCore.Qt.Key_Escape: 
     print("esc") 

sonunda ZetCode göreceğiniz gibi.

+0

Bunların hepsini test ettiniz mi? Destroy() 'işlevini çağırmak, widget'ı siler ve uygulamayı durdurmak için hiçbir araç kullanmadan bırakacaktır, ki bu kesinlikle doğru olan şey değildir. Ayrıca, OP'nin de dediği gibi 'keyPressEvent 'çalışır, bu yüzden değiştirmeye gerek yoktur. – ekhumoro

+0

@ekhumoro Hayır Yapmadım. Düzeltildi. Sadece bu durumda çalışmayan event.accept() seçeneğine alternatif oluşturmak istedim. Başları için teşekkürler. Esc gelince, başka türlü söylemedim. Sadece neler olduğunu açıkladım ve kullanıcının ihtiyaç duyduğu durumlarda varsayılan davranışı geçersiz kılacak kodu sağladım. Cevabımda daha eksiksiz olma meselesiydi. – armatita

İlgili konular