Python Forum
[PyQt] QGraphicsScene / QGraphicsView: Origin and Positive Values
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
[PyQt] QGraphicsScene / QGraphicsView: Origin and Positive Values
#1
Hi,

Is there a built-in way of setting 0,0 to the centre of the page?

Also is there a way to make positive Y go up instead of down?


* I'm guessing that there won't be, so I'm embarking on wrapping all my Items in QGraphicsItemGroup, but thought I'd ask anyway!

Thankyou
Reply
#2
Zoom All is a bit odd, but here's how that test went... Any pointers greatly appreciated!
#	https://stackoverflow.com/questions/39614777/how-to-draw-a-proper-grid-on-pyqt

import sys
from PyQt5.QtCore import Qt, QRectF, QPointF
from PyQt5.QtGui import QBrush, QPainter, QPen, QColor, QTransform, QLinearGradient
from PyQt5.QtWidgets import (
	QApplication,
	QMainWindow,
	QWidget,
	QGraphicsScene,
	QGraphicsView,
	QHBoxLayout,
	QVBoxLayout,
	QPushButton,
	
	QGraphicsItem,
	QGraphicsLineItem,
	
	QGraphicsItemGroup
)

class Settings():
	WIDTH = 10
	HEIGHT = 10
	NUM_BLOCKS_X = 100
	NUM_BLOCKS_Y = 100


class QGS(QGraphicsScene):
	
	def __init__(self, *args, **kwargs):
		super().__init__(*args, **kwargs)
		
		self.settings = Settings()
		
		#	SET PAGE
		self.page_width = self.settings.NUM_BLOCKS_X * self.settings.WIDTH
		self.page_height = self.settings.NUM_BLOCKS_Y * self.settings.HEIGHT
		self.setSceneRect(0, 0, self.page_width, self.page_height)
		self.setItemIndexMethod(QGraphicsScene.NoIndex)
		
		#	CALC ORIGIN
		pos_x = (self.settings.NUM_BLOCKS_X / 2) * self.settings.WIDTH
		pos_y = (self.settings.NUM_BLOCKS_Y / 2) * self.settings.HEIGHT
		self.origin = QPointF(pos_x, pos_y)
		
		#	GRID
		self.lines = []
		self.draw_grid()
		self.set_opacity(0.3)
		#self.set_visible(False)
		#self.delete_grid()
		
		#	DRAW ORIGIN
		self.draw_origin()

	def draw_grid(self):
		
		pen = QPen(QColor(222, 222, 255), 1, Qt.SolidLine)

		for x in range(0, self.settings.NUM_BLOCKS_X+1):
			xc = x * self.settings.WIDTH
			self.lines.append(self.addLine(xc, 0, xc, self.page_height, pen))

		for y in range(0, self.settings.NUM_BLOCKS_Y+1):
			yc = y * self.settings.HEIGHT
			self.lines.append(self.addLine(0, yc, self.page_width, yc, pen))

	def set_visible(self,visible=True):
		for line in self.lines:
			line.setVisible(visible)

	def delete_grid(self):
		for line in self.lines:
			self.removeItem(line)
		del self.lines[:]

	def set_opacity(self,opacity):
		for line in self.lines:
			line.setOpacity(opacity)
	
	def draw_origin(self):
		#	X AXIS
		ax = self.addLine(0, 0, 100, 0, Qt.red)
		#ax.setPos(pos_x, pos_y)
		ax.setPos(self.origin)
		
		#	Y AXIS
		ay = self.addLine(0, 0, 0, 100, Qt.green)
		#ay.setPos(pos_x, pos_y)
		ay.setPos(self.origin)


class Win(QMainWindow):
	
	view_scales = [0.2, 0.4, 0.6, 0.8, 1.0, 1.5, 2.0, 3.0]
	view_scale_current = 4
	
	def __init__(self):
		super().__init__()
		
		#	GRAPHICS SCENE & VIEW
		#self.scene = QGraphicsScene(0, 0, 2400, 2400)
		#self.scene = QGV.QGS(0, 0, 2400, 2400)
		self.scene = QGS(0, 0, 2400, 2400)
		self.view = QGraphicsView(self.scene)
		self.view.setRenderHint(QPainter.Antialiasing)
		
		
		self.pen_line = QPen(Qt.black)
		self.pen_line.setWidth(1)
		#o.setPen(self.pen_line)
		
		#	TEST TOOLBAR
		toolbox = QHBoxLayout()
		
		btn_out = QPushButton("-")
		btn_out.clicked.connect(self.view_scale_out)
		toolbox.addWidget(btn_out)
		
		btn_in = QPushButton("+")
		btn_in.clicked.connect(self.view_scale_in)
		toolbox.addWidget(btn_in)
		
		btn_all = QPushButton("ALL")
		btn_all.clicked.connect(self.view_scale_all)
		toolbox.addWidget(btn_all)
		
		btn_reset = QPushButton("RESET")
		btn_reset.clicked.connect(self.view_scale_reset)
		toolbox.addWidget(btn_reset)
		
		#	MAIN LAYOUT
		vbox = QVBoxLayout()
		vbox.addWidget(self.view)
		vbox.addLayout(toolbox)
		
		#	WINDOW LAYOUT
		widget = QWidget()
		widget.setLayout(vbox)
		self.setCentralWidget(widget)
		
		#	LOAD DRAWING
		self.dwg_load()
	
	def dwg_load(self):
		#	TMP
		self.add_object({"type":"LINE", "pos":[0, 0], "v1":[10, 10], "v2":[100, 10]})
		self.add_object({"type":"LINE", "pos":[0, 0], "v1":[10, 20], "v2":[100, 100]})
		self.add_object({"type":"LINE", "pos":[150, 50], "v1":[0, 0], "v2":[100, 100]})
		
	def add_object(self, data):
		
		o = QGraphicsItemGroup()
		
		if data["type"] == "LINE":
			e = QGraphicsLineItem()	#0, 0, 200, 50)
			e.setPos(data["pos"][0], data["pos"][1]*-1)
			#e.setLine(data["v1"][0], data["v1"][1], data["v2"][0], data["v2"][1])
			e.setLine(data["v1"][0], data["v1"][1]*-1, data["v2"][0], data["v2"][1]*-1)
			e.setPen(self.pen_line)
			e.setData(0, data)
			o.addToGroup(e)
		
		
		
		
		#	PROPERTIES
		o.setFlag(QGraphicsItem.ItemIsMovable)
		o.setFlag(QGraphicsItem.ItemIsSelectable)
		
		#	!!! NOW SET ORIGIN POS
		o.setPos(self.scene.origin)
		o.setData(0, {"type":"g"})
		self.scene.addItem(o)
		
	def view_scale_out(self):
		self.view_scale_current -= 1
		if self.view_scale_current < 0:
			self.view_scale_current = 0
		self.view.setTransform(QTransform())
		self.view.scale(self.view_scales[self.view_scale_current], self.view_scales[self.view_scale_current])
		print("View Scale:", self.view_scales[self.view_scale_current], ", ", self.view_scale_current)
		
	def view_scale_in(self):
		self.view_scale_current += 1
		if self.view_scale_current > len(self.view_scales)-1:
			self.view_scale_current = len(self.view_scales)-1
		self.view.setTransform(QTransform())
		self.view.scale(self.view_scales[self.view_scale_current], self.view_scales[self.view_scale_current])
		print("View Scale:", self.view_scales[self.view_scale_current], ", ", self.view_scale_current)
	
	def view_scale_reset(self):
		self.view.setTransform(QTransform())
		self.view.scale(1.0, 1.0)
		self.view_scale_current = 4
		print("View Scale:", self.view_scales[self.view_scale_current], ", ", self.view_scale_current)
		
	def view_scale_all(self):
		print("ZOOM ALL")
		
		#items = self.scene.selectedItems()
		items = self.scene.items()
		
		#	CALC BOUNDS
		min_x = sys.float_info.max
		max_x = sys.float_info.min
		min_y = sys.float_info.max
		max_y = sys.float_info.min
		#i = 0
		for item in items:
			d = item.data(0)
			if d != None and d["type"] == "g":
				#bb = self.obj_bounds(item)
				#br = item.sceneBoundingRect()
				br = item.childrenBoundingRect()
				br.translate(item.pos())
				#br.moveTo(item.pos())
				#br.moveCenter(item.pos())
				
				#	TOP LEFT
				if br.left() < min_x:
					min_x = br.left()
				
				if br.top() < min_y:
					min_y = br.top()
				
				#	BOTTOM RIGHT
				if br.right() > max_x:
					max_x = br.right()
				
				if br.bottom() > max_y:
					max_y = br.bottom()
				
		
		self.view.fitInView(QRectF(min_x, min_y, max_x, max_y), Qt.KeepAspectRatio)
		#	IgnoreAspectRatio, KeepAspectRatio, KeepAspectRatioByExpanding
		
		self.view.repaint()
		

if __name__ == '__main__':
	app = QApplication(sys.argv)
	w = Win()
	w.show()
	sys.exit(app.exec_())
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  [closed] "checked" variable (attribute?) origin? paul18fr 4 3,654 Mar-05-2024, 04:20 PM
Last Post: deanhystad
  QPixmap not updating in QGraphicsScene after using QPainter on it Leo_Red 1 3,358 Apr-15-2022, 07:09 PM
Last Post: deanhystad

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020