2012-02-29 41 views
8

Tôi đang cố gắng hiểu về QGraphicsView và QGraphicsScene, cụ thể là cách đặt các mục đồ họa và để chúng xuất hiện ở nơi tôi muốn chúng. Tôi cũng bối rối khi thanh cuộn sẽ xuất hiện nếu cảnh lớn hơn vùng xem.PyQt: Cố gắng hiểu cảnh đồ họa/xem

Ví dụ, chút mã này sẽ tạo ra một hình ảnh nhỏ xem với một hình elip ở góc trên cùng:

import sys 
from PyQt4 import QtGui, QtCore 

class MyView(QtGui.QGraphicsView): 
    def __init__(self): 
     QtGui.QGraphicsView.__init__(self) 

     self.scene = QtGui.QGraphicsScene(self) 
     self.scene.setSceneRect(QtCore.QRectF(0, 0, 245, 245)) 

     self.setScene(self.scene) 

     self.item = QtGui.QGraphicsEllipseItem(0, 0, 60, 40) 
     self.scene.addItem(self.item) 


if __name__ == '__main__': 
    app = QtGui.QApplication(sys.argv) 
    view = MyView() 
    view.show() 
    sys.exit(app.exec_()) 

Tuy nhiên, nếu self.scene.setSceneRect(QtCore.QRectF(0, 0, 245, 245)) được bỏ qua, thì hình elip xuất hiện ở giữa cửa sổ mặc dù hình elip có x, y = 0,0. Tôi cung không chăc tại sao! Có lý do nào cho hành vi này không?

Tương tự như vậy, tôi nhầm lẫn về sự xuất hiện của thanh cuộn khi kích thước khung cảnh lớn hơn chế độ xem. Ví dụ: mã sau tạo một chế độ xem/cảnh với một số dấu ba chấm và itemsBoundingRect lớn hơn sceneRect. Chỉ có một số dấu ba chấm được hiển thị, nhưng không có thanh cuộn để xem các dấu bị ẩn, bạn phải tăng kích thước của cửa sổ. Nhưng khi bạn làm điều đó, vị trí của các elip thay đổi, vì vậy x, y của các bầu dục bị bỏ qua.

import sys 
from PyQt4 import QtGui, QtCore 

class MyView(QtGui.QGraphicsView): 
    def __init__(self): 
     QtGui.QGraphicsView.__init__(self) 

     self.setGeometry(QtCore.QRect(100, 100, 250, 250)) 

     self.scene = QtGui.QGraphicsScene(self) 
     self.scene.setSceneRect(QtCore.QRectF(0, 0, 200, 200)) 

     self.setScene(self.scene) 

     for i in range(5): 
      self.item = QtGui.QGraphicsEllipseItem(i*75, 10, 60, 40) 
      self.scene.addItem(self.item) 


if __name__ == '__main__': 
    app = QtGui.QApplication(sys.argv) 
    view = MyView() 
    view.show() 
    sys.exit(app.exec_()) 

Nếu dòng self.scene.setSceneRect(QtCore.QRectF(0, 0, 200, 200)) bị bỏ qua, sau đó thanh cuộn sẽ xuất hiện. Nhưng một lần nữa, vị trí x, y của các elip được bỏ qua, và chúng được căn giữa trong khung nhìn.

Điều tôi đang cố gắng là: tạo chế độ xem nơi các mục đến nơi tôi muốn và nếu số mục làm cho cảnh lớn hơn kích thước xem, cho thanh cuộn xuất hiện nhưng đối với x, y vị trí của các đối tượng được duy trì.

Tôi cảm thấy như tôi đang thiếu một số phần quan trọng của câu đố xem/cảnh ...

Trả lời

3

Từ tài liệu

Nếu rect cảnh là unset, PySide.QtGui.QGraphicsScene sẽ sử dụng vùng giới hạn của tất cả> các mục, như được trả về bởi PySide.QtGui.QGraphicsScene.itemsBoundingRect(), như cảnh rect.

Vì vậy, nó sẽ đặt trực tiếp hình ảnh của bạn làm cảnh quay và tâm của cảnh là trung tâm của tiện ích.

Thanh cuộn sẽ xuất hiện khi cảnh quay lớn hơn kích thước tiện ích. Khi bạn nhận xét ra dòng setSceneRect, cảnh của bạn đang được tự động thay đổi kích thước nhưng khi bạn có đường, hình ảnh của bạn đang được thêm vào qua các giới hạn của scenRect, do đó bạn sẽ phải cập nhật sceneRect để hiển thị.

+0

Cảm ơn @Jeff. Tôi đã nhận thấy cuộc gọi 'setGeometry' cũng đóng một vai trò khi thanh cuộn xuất hiện. Trong ví dụ thứ hai, các thanh cuộn xuất hiện khi 'setGeometry' được gọi nhưng' setSceneRect' được gọi là _not_. Đương nhiên, nếu không được gọi, chế độ xem sẽ tự động điều chỉnh để phù hợp với tất cả các mục (tuân theo 'itemsBoundingRect'). Nếu _both_ được gọi, thì chỉ có cảnh được xác định bởi 'setSceneRect' được hiển thị, không có thanh cuộn. – XandYandZ

1
import sys from PyQt4 import QtGui, QtCore 

class MyView(QtGui.QGraphicsView): 
    def __init__(self): 
     QtGui.QGraphicsView.__init__(self) 

     self.setGeometry(QtCore.QRect(100, 100, 600, 250)) 

     self.scene = QtGui.QGraphicsScene(self) 
     self.scene.setSceneRect(QtCore.QRectF()) 

     self.setScene(self.scene) 

     for i in range(5): 
      self.item = QtGui.QGraphicsEllipseItem(i*75, 10, 60, 40) 
      self.scene.addItem(self.item) 


if __name__ == '__main__': 
    app = QtGui.QApplication(sys.argv) 
    view = MyView() 
    view.show() 
    sys.exit(app.exec_()) 
Các vấn đề liên quan