Teilkreislinie ohne Winkellinie zeichnen

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Nobuddy
User
Beiträge: 997
Registriert: Montag 30. Januar 2012, 16:38

Hallo zusammen,
möchte Teilkreislinie ohne Winkellinie zeichnen.
Dazu habe ich hier ein Beispiel, damit Ihr versteht was ich meine.

Code: Alles auswählen

from PyQt5.QtCore import (
	Qt,
	QEvent,
	)
from PyQt5.QtWidgets import (
	QApplication,
	QGraphicsView,
	QGraphicsScene,
	QGraphicsItem,
	QGraphicsEllipseItem,
	)
from PyQt5.QtGui import  (
	QPen,
	QBrush,
	)

class GeometryDraw(QGraphicsView):
	def __init__(self, anglecircles=None):
		super(GeometryDraw, self).__init__()

		self.viewport().installEventFilter(self)
		self.scene = QGraphicsScene(self)
		self.setScene(self.scene)
		try:
			self.anglecircles(anglecircles)
		except TypeError:
			pass
		self.setCacheMode(QGraphicsView.CacheBackground)
		self.show()

	def anglecircles(self, anglecircles):
		for x, y, d, startangle, spanangle, color in anglecircles:
			circle = QGraphicsEllipseItem(x, y, d, d)
			circle.setStartAngle(startangle)
			circle.setSpanAngle(spanangle)
			self.finish(color, circle)

	def finish(self, color, item):
		pen = QPen()
		pen.setBrush(QBrush(color))
		item.setPen(pen)
		item.setFlags(QGraphicsItem.ItemIsMovable |
			QGraphicsItem.ItemIsSelectable)
		self.scene.addItem(item)


def main():
	import sys

	startangle = 0
	alpha = 121.081
	spanangle = int(alpha*16)
	r0 = 148.660
	r1 = 74.330
	anglecircles = [
		(-r0, -r0, r0*2, startangle, spanangle, Qt.green),
		(-r1, -r1, r1*2, startangle, spanangle, Qt.green),
		]
	app = QApplication(sys.argv)
	obj = GeometryDraw(anglecircles=anglecircles)
	sys.exit(app.exec_())

if __name__ == '__main__':
	main()
Hoffe, Ihr könnt mir dabei helfen!

Grüße Nobuddy
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Mir fehlt hier die Problembeschreibung. Was geht denn nicht?
Benutzeravatar
__blackjack__
User
Beiträge: 13150
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Ich vermute es soll nur der Bogen gezeichnet werden, ohne die beiden geraden Linien.
“There will always be things we wish to say in our programs that in all known languages can only be said poorly.” — Alan J. Perlis
Nobuddy
User
Beiträge: 997
Registriert: Montag 30. Januar 2012, 16:38

__blackjack__, genau um dies Linien handelt es sich.
Gibt es da was, um die Linien zu unterbinden, oder muss ich die unerwünschten Linien mit der Hintergrundfarbe nachzeichnen, damit diese nicht mehr sichtbar sind?
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Das wird die Outline sein, und die kontrolliert man mit dem brush. https://doc.qt.io/qt-6/qabstractgraphic ... l#setBrush
Benutzeravatar
__blackjack__
User
Beiträge: 13150
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@__deets__: Das gilt dann aber auch für die gesamte Umrandung, also für Bogen *und* die beiden Linien. Soweit ich das nach einem kurzen Blick gesehen habe geht da nix mit der Ellipse.
“There will always be things we wish to say in our programs that in all known languages can only be said poorly.” — Alan J. Perlis
Nobuddy
User
Beiträge: 997
Registriert: Montag 30. Januar 2012, 16:38

Hallo und Danke, für Eure Infos!
Werde dies im Moment zurückstellen, da ich erst die Originalgröße erreichen möchte.
Die Grafik soll ausgedruckt und als Schablone zum Ausschneiden verwendet werden.

In meinem kleinen Codebeispiel ist:
r0 = 148.660 mm
r1 = 74.330 mm
Wie bekomme ich die Originalgröße der Grafik in der Ausgabe hin?
Welchen Umrechnungsfaktor muss dafür verwendet werden?

Grüße Nobuddy
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Puh. Das ist ein Bereich, den ich noch nie beackern musste. Ich würde mit https://doc.qt.io/qt-6/qprinter.html rumspielen, laut https://forum.qt.io/topic/14952/render- ... export-pdf zb kann man eine scene auf den printer Rendern. Aber was da skalierungsmässig passiert, kann ich nicht nachvollziehen, ohne da selbst viel Zeit zu investieren.
Benutzeravatar
__blackjack__
User
Beiträge: 13150
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Nobuddy: Das sollte sich aus Quell- und Ziel-Rect von der `render()`-Methode auf `QQgraphicsScene` ergeben. Siehe zum Beispiel hier: https://stackoverflow.com/a/37712154/3815611
“There will always be things we wish to say in our programs that in all known languages can only be said poorly.” — Alan J. Perlis
Nobuddy
User
Beiträge: 997
Registriert: Montag 30. Januar 2012, 16:38

Danke für die Infos, werde diese durcharbeiten :wink:
Nobuddy
User
Beiträge: 997
Registriert: Montag 30. Januar 2012, 16:38

Beim Googeln zum Thema: Fensterausgabe in mm, bin ich darauf gestoßen
import sys
from PyQt5.QtWidgets import QApplication
app = QApplication(sys.argv)
screen = app.screens()[0]
dpi = screen.physicalDotsPerInch()
factor = dpi/25.4
app.quit()
und habe den Faktor für die Umrechnung von mm zur original Ausgabe im Fenster.
In meinem Beispiel, ist der Faktor 4.187264093510288.

Habe dies mal bei meinem Beispielcode umgesetzt.

Code: Alles auswählen

from PyQt5.QtCore import (
	Qt,
	QEvent,
	)
from PyQt5.QtWidgets import (
	QApplication,
	QGraphicsView,
	QGraphicsScene,
	QGraphicsItem,
	QGraphicsEllipseItem,
	)
from PyQt5.QtGui import  (
	QPen,
	QBrush,
	)

class GeometryDraw(QGraphicsView):
	def __init__(self, anglecircles=None):
		super(GeometryDraw, self).__init__()

		self.viewport().installEventFilter(self)
		self.scene = QGraphicsScene(self)
		self.setScene(self.scene)
		try:
			self.anglecircles(anglecircles)
		except TypeError:
			pass
		self.setCacheMode(QGraphicsView.CacheBackground)
		self.show()

	def anglecircles(self, anglecircles):
		for x, y, d, startangle, spanangle, color in anglecircles:
			circle = QGraphicsEllipseItem(x, y, d, d)
			circle.setStartAngle(startangle)
			circle.setSpanAngle(spanangle)
			self.finish(color, circle)

	def finish(self, color, item):
		pen = QPen()
		pen.setBrush(QBrush(color))
		item.setPen(pen)
		item.setFlags(QGraphicsItem.ItemIsMovable |
			QGraphicsItem.ItemIsSelectable)
		self.scene.addItem(item)


def main():
	import sys

	startwinkel = 0
	startangle = int(startwinkel*16)
	alpha = 121.081
	spanangle = int(alpha*16)
	r0 = 148.660
	r1 = 74.330
	app = QApplication(sys.argv)
	screen = app.screens()[0]
	dpi = screen.physicalDotsPerInch()
	factor = dpi/25.4
	anglecircles = [
		(-r0*factor, -r0*factor, r0*factor*2, startangle, spanangle, Qt.green),
		(-r1*factor, -r1*factor, r1*factor*2, startangle, spanangle, Qt.green),
		]
	obj = GeometryDraw(anglecircles=anglecircles)
	sys.exit(app.exec_())

if __name__ == '__main__':
	main()
Habe mit einem Lineal am Bildschirm abgemessen und muss feststellen, die Maße stimmen.
Hoffe ich liege da richtig?
Dann könnte ich mich um den Druck kümmern.

Grüße Nobuddy
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Klingt an sich gut, aber nur Versuch macht kluch.
Nobuddy
User
Beiträge: 997
Registriert: Montag 30. Januar 2012, 16:38

so isses :wink:
Benutzeravatar
__blackjack__
User
Beiträge: 13150
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Nobuddy: Zum Quelltext: Widgets zeigen sich nicht selbst an, das entscheidet der Code der das erstellt und irgendwo einbaut. Und `obj` könnte man einen besseren Namen geben.

Wie kann `anglecircles` gleichzeitig der Name von Daten und einer Methode sein? Und was sollte da drin sein dürfen das einen `TypeError` verursachen kann der die Abarbeitung abbricht, ohne dass da sonst irgendwer was von mitbekommt?

Mir persönlich wären Tupel mit sechs Elementen in der Regel schon zu viel für ein Tupel wo man dann wissen muss was an welchem Index steht, ohne dass die Elemente über sinnvolle Namen ansprechbar sind.

ZwischenWortensolltemanLeerzeichen,beziehungsweiseinNamenUnterstrichesetzen.

Spannend ist auch `startwinkel` und `startangle` dicht beieinander im gleichen Namensraum. Was bedeutet das denn und was ist der Unterschied zwischen dem einen Start-Winkel und dem anderen Start-Winkel?
“There will always be things we wish to say in our programs that in all known languages can only be said poorly.” — Alan J. Perlis
Nobuddy
User
Beiträge: 997
Registriert: Montag 30. Januar 2012, 16:38

__blackjack__, ist eigentlich fast der gleiche Code, wie zu Anfang meines Posts , warum ist das Dir nicht gleich aufgefallen.

Einen besseren Namen für obj, vielleicht geo_obj?

Gleicher Namen für Daten und Methode, das werde ich ändern.
Einen TypeError gibt es nur bei einem bool Wert.

Tupel mit sechs Elementen, da gibt es bestimmt eine andere Lösung.
Unterstriche für besseres Lesen, ist sinnvoll.

Mir ist nicht ganz klar, wo bei startangle und spanangle das Problem ist.
Der erste startwinkel ist in Gradangabe, daraus erfolgt die Umrechnung und das Attribute startangle. Das Gleiche auch bei alpha und spanangle.
Was Du mit "Unterschied zwischen dem einen Start-Winkel und dem anderen Start-Winkel" meinst, ist mir nicht klar.

Dieser Code dient als Beispiel und soll zur Nachvollziehbarkeit der Helfenden dienen.
Ich nehme Kritik immer Ernst ... und daraus lernen.
Vielleicht hast Du zum Einen oder Anderen ein kurzes Beispiel!

Grüße Nobuddy
Benutzeravatar
__blackjack__
User
Beiträge: 13150
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Nobuddy: Aber warum sollte da ein `bool`-Wert vorkommen?

Bei `startangle` und `spanangle` ist nur der fehlende Unterstrich das Problem. `startangle` heisst Start-Winkel. `startwinkel` heisst auch Start-Winkel. Die Unterscheiden sich nur dadurch dass das eine Deutsch und das andere Englisch benannt ist, aber es ist ja letztlich inhaltlich beides der gleiche Name. Bedeutet aber anscheinend was anderes. Was aus dem Namen nicht ersichtlich wird.
“There will always be things we wish to say in our programs that in all known languages can only be said poorly.” — Alan J. Perlis
Nobuddy
User
Beiträge: 997
Registriert: Montag 30. Januar 2012, 16:38

__blackjack__, das mit startangle/startspan, habe ich verstanden. Aus startangle/startspan wird start_angle/start_span.
Das mit startwinkel, sind letztendlich zwei verschiedene Inhalte. Der erste startwinkel ist in Grad und müsste dann startwinkel_grad heißen.

Das mit dem bool Wert und dem TypeError ergibt sich aus:

Code: Alles auswählen

class GeometryDraw(QGraphicsView):
	def __init__(self, anglecircles=None):
Benutzeravatar
__blackjack__
User
Beiträge: 13150
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Nobuddy: Da reagiert man dann aber nicht auf eine Ausnahme sondern ruft die Funktion/Methode gar nicht erst mit einem falschen Typ auf. Entweder vorher prüfen oder ein leeres Tupel statt `None` als Default-Wert.
“There will always be things we wish to say in our programs that in all known languages can only be said poorly.” — Alan J. Perlis
Nobuddy
User
Beiträge: 997
Registriert: Montag 30. Januar 2012, 16:38

__blackjack__, Danke für die Info, das vereinfacht das !
Das wußte ich vorher nicht.

Code: Alles auswählen

class GeometryDraw(QGraphicsView):
	def __init__(self, anglecircles=[ ]):
Antworten