2012-01-21 48 views
18

Tôi muốn thực hiện hành động khi tiện ích được thay đổi kích thước.QWidget đổi kích cỡ tín hiệu?

Có cách nào để nắm bắt điều đó mà không cần cài đặt bộ lọc sự kiện trên tiện ích đó (và, hiển nhiên, không có phân lớp phụ)? AFAIK, QWidget không có tín hiệu resized.

+4

Không, bạn không thể. Cách bset là: Tạo QWidget của riêng bạn phát ra Resize trong resizeEvent(), sau đó thúc đẩy các widget của bạn vào nó :) –

Trả lời

11

Nếu bạn có bất kỳ QObject khác có thể có mối quan hệ chặt chẽ với QWidget bạn có thể sử dụng QObject::installEventFilter(QObject * filter) và quá tải bool eventFilter(QObject *, QEvent *). Xem thêm tại Qt docs

17

Bạn có thể bắt nguồn từ widget lớp và reimplement resizeEvent kiện

+0

lưu ý rằng warwaruk đã viết "và rõ ràng là không có phân lớp" –

+0

@KamilKlimek, ...sau khi tôi đăng câu trả lời :) – Lol4t0

+0

không nhận thấy rằng, số –

9

Trong trường hợp bạn đang sử dụng Python với PyQt4, bạn có thể đặt widget.resizeEvent đến chức năng của bạn mà không cần sublclassing nó:

#!/usr/bin/env python 
import sys 
from PyQt4 import QtCore, QtGui 

def onResize(event): 
    print event 

if __name__ == "__main__": 
    app = QtGui.QApplication(sys.argv) 
    widget = QtGui.QPushButton('Test') 
    widget.resizeEvent = onResize 
    widget.resize(640, 480) 
    widget.show() 
    sys.exit(app.exec_()) 
+5

Điều này ngăn cản việc thực thi lớp cơ sở của resizeEvent chạy. Nó có thể làm điều gì đó quan trọng. Và với giải pháp vá lỗi khỉ, bạn phải giữ tham chiếu đến phương thức gốc dưới dạng biến riêng biệt. Lộn xộn. – Chris

+2

@Chris Các tài liệu nói rằng vào thời gian thay đổi kích thướcEvent được gọi là widget đã có hình học mới của nó vì vậy nếu bạn không có bất cứ điều gì khác để làm trên widget chính, bạn chỉ có thể ghi đè lên các chức năng. Tôi sử dụng kỹ thuật này để thay đổi kích thước nội dung của QScrollArea. – blameless75

2

Xin lỗi, có vẻ như một hack, nhưng tôi sử dụng này:

some_widget.resizeEvent = (lambda old_method: (lambda event: (self._on_resized(event), old_method(event))[-1]))(some_widget.resizeEvent) 
+2

Rất nhiều cho Python được thiết kế cho tính dễ đọc. Tuy nhiên, +1 để duy trì việc triển khai siêu. –

2

Đây là một vài năm quá muộn, nhưng tôi đã làm việc trên một tiện ích lớp phủ trong suốt hoàn toàn bao gồm phụ huynh. Bạn không thể làm những gì bạn muốn mà không có phân lớp, nhưng bạn có thể hạn chế phân lớp thành một thể hiện như @reclosedev gợi ý, nghĩa là bạn không phải tạo một lớp con.

tôi đã viết đoạn sau (trong đó hoạt động trong PyQt4) cho sau kích thước của bất kỳ widget widget được thêm vào:

class TransparentOverlay(QtGui.QWidget): 
    def __init__(self, *args, **kwargs): 
     super().__init__(*args, **kwargs) 
     self.setAttribute(QtCore.Qt.WA_NoSystemBackground) 
     self._updateParent(self.parentWidget()) 

    def setParent(self, parent, *args): 
     prevParent = self.parentWidget() 
     super().setParent(parent, *args) 
     self._updateParent(parent, prevParent) 

    def unsetParent(self, parent=None): 
     if parent is None: 
      parent = self.parentWidget() 
     if parent is not None and hasattr(parent.resizeEvent, '_original'): 
      parent.resizeEvent = parent.resizeEvent._original 

    def _updateParent(self, parent, prevParent=None): 
     if parent is not prevParent: 
      self.unsetParent(prevParent) 
      if parent is not None: 
       original = parent.resizeEvent 
       def resizeEventWrapper(event): 
        original(event) 
        self.resize(event.size()) 
       resizeEventWrapper._original = original 
       parent.resizeEvent = resizeEventWrapper 
       self.resize(parent.size()) 

Mã này sử dụng một vài thủ thuật gọn gàng mà có thể xảy ra với Python:

  • Phương thức gốc được lưu giữ trong thuộc tính _original của thuộc tính mới. Điều này là có thể bởi vì các hàm là các đối tượng.
  • Phương thức mới thực sự phân lớp bất kỳ QWidgetdụ, có nghĩa là bạn không phải tạo một lớp con thực sự. Mỗi cá thể cha mẹ sẽ có hiệu quả trở thành một thể hiện của một lớp con nhờ vào phương pháp được giải quyết.

Nếu bạn cần điều một lần, tất cả mã để xóa phương thức resizeEvent được phân lớp và thay thế bằng mã gốc có thể được chuyển vào thùng rác. Trong trường hợp đó, giải pháp cơ bản là một phiên bản fancier của giải pháp @ reclosedev, nhưng với ý kiến ​​của @ Chris về việc bảo quản địa chỉ gốc.

Thông báo trước với mã này là nó không hỗ trợ tiện ích GL chính xác, vì vậy, ví dụ: lớp phủ không phải lúc nào cũng được thêm vào chế độ xem của QGraphicsView. Nó có thể, tuy nhiên, được thêm vào chính nó là QGraphicsView.

2

Bạn có thể ghi đè lên resizeEvent bởi

def resizeEvent(self, newSize): 
    #do code here 
Các vấn đề liên quan