Geometrische Objekte werden generiert, aber nicht angezeigt.

Python und das Qt-Toolkit, erstellen von GUIs mittels des Qt-Designers.
__deets__
User
Beiträge: 14494
Registriert: Mittwoch 14. Oktober 2015, 14:29

Atalanttore
User
Beiträge: 407
Registriert: Freitag 6. August 2010, 17:03

Wenn `path` ein `QPainterPath`-Objekt und `scene` ein `QGraphicsScene`-Objekt ist, schreibt man das dann so:

Code: Alles auswählen

scene.setSelectionArea(path)
selected = scene.selectedItems()
Es wäre toll, wenn `selected` dann eine Liste mit den noch sichtbaren Objekten enthält. Ist das der Fall?

Gruß
Atalanttore
__deets__
User
Beiträge: 14494
Registriert: Mittwoch 14. Oktober 2015, 14:29

Ich wuerde eher mit der zweiten Option operieren, die Selektion ist sicher moeglich, aber mir persoenlich zu viel Seiteneffekt - die Selektion hat ja ggf. auch noch andere Einsatzzwecke.

Und hast du das mal probiert? Du hast doch inzwischen ausreichend viel Code, um damit mal rumzuspielen.
Atalanttore
User
Beiträge: 407
Registriert: Freitag 6. August 2010, 17:03

Also eher so:

Code: Alles auswählen

scene.setSelectionArea(path)
selected = scene.items()
Gruß
Atalanttore
__deets__
User
Beiträge: 14494
Registriert: Mittwoch 14. Oktober 2015, 14:29

Hast du dir die items-calls mal angeschaut? Das sind jede Menge. Mit Argumenten für eine Zone (als rect oder Pfad und so)

Also präzise wonach du gefragt hast.
Atalanttore
User
Beiträge: 407
Registriert: Freitag 6. August 2010, 17:03

@__deets__: Die C++-Codeschnipsel der Methodenaufrufe sind für mich wenig verständlich.
  1. Was meinst du mit "items-calls"?
  2. Was ist eine Zone bei Qt?
Gruß
Atalanttore
__deets__
User
Beiträge: 14494
Registriert: Mittwoch 14. Oktober 2015, 14:29

Alle die Aufrufe die items heissen. Und verschiedene Argumente akzeptieren, um die items die in einer bestimmten Zone oder Region sind. Das willst du doch.
Atalanttore
User
Beiträge: 407
Registriert: Freitag 6. August 2010, 17:03

Eigentlich wollte ich nur eine einfache Möglichkeit zum Erkennen, wenn ein Objekt für den Nutzer nicht mehr sichtbar ist.

Ist ein `QGraphicsScene`-Objekt eine Zone oder Region?

Gruß
Atalanttore
__deets__
User
Beiträge: 14494
Registriert: Mittwoch 14. Oktober 2015, 14:29

Diese Methoden sind eine Möglichkeit - wenn du die sichtbare Region (die dann ein Rechteck ist) zur Abfrage nutzt, dann erhältst du die sichtbaren items zurück.

Aber warum willst du das? Die Kombination aus view und Scene löst das doch für dich.

Und die Scene ist keine Region. Sondern ein Sack voller Objekte.
Atalanttore
User
Beiträge: 407
Registriert: Freitag 6. August 2010, 17:03

@__deets__: Meinst du mit "view" ein `QGraphicsView`-Objekt?

Gruß
Atalanttore
__deets__
User
Beiträge: 14494
Registriert: Mittwoch 14. Oktober 2015, 14:29

Ja.
Atalanttore
User
Beiträge: 407
Registriert: Freitag 6. August 2010, 17:03

@__deets__: Werden Objekte außerhalb einer `QGraphicsView` automatisch gelöscht?

Gruß
Atalanttore
__deets__
User
Beiträge: 14494
Registriert: Mittwoch 14. Oktober 2015, 14:29

Nein. Aber sie werden effizient ausgefiltert. All das steht auch in der Doku. Und solange du kein Problem hast, musst du auch keines lösen. Hast du eines?
Atalanttore
User
Beiträge: 407
Registriert: Freitag 6. August 2010, 17:03

Schön, wenn man sich um die Entfernung von enteilten Objekten nicht zu kümmern braucht.

Gruß
Atalanttore
__deets__
User
Beiträge: 14494
Registriert: Mittwoch 14. Oktober 2015, 14:29

Endlos geht das natürlich nicht. Aber das ganze ist explizit konstruiert worden um effizient zu filtern, was nicht sichtbar ist. Solange du also kein Problem hast, musst du dich auch nicht grämen. Wenn du eines bekommst, ist die Frage nach “was ist sichtbar” mit den genannten Methoden und http://doc.qt.io/qt-5/qgraphicsview.html#sceneRect-prop als Argument ermitteln.
Atalanttore
User
Beiträge: 407
Registriert: Freitag 6. August 2010, 17:03

Dann kann ich weiter an meiner Erweiterung basteln. Allerdings muss ich auch noch ein anderes Problem dafür lösen, aber das ist in einem anderen Thema.

Gruß
Atalanttore
Atalanttore
User
Beiträge: 407
Registriert: Freitag 6. August 2010, 17:03

Zum Einbau einer Erweiterung habe ich an den Stellschrauben im Code gedreht, damit es mehr nach Weltraum aussieht. Dabei ist mir aufgefallen, dass wieder mal (wie bei Tkinter) ein dünner weißer Rahmen um den schwarzen Hintergrund gezeichnet wird. Vor allem im Vollbildmodus sieht man den Rahmen. Wie bekommt man bei Qt diesen Rahmen weg?

Code:

Code: Alles auswählen

import random
import time
import sys

from PyQt5 import QtCore
from PyQt5.QtWidgets import QApplication, QGraphicsView, QGraphicsScene
from PyQt5.QtGui import QPainterPath, QPolygonF


SPEED = 5000
MIN_DISTANCE = 30000
DISTANCE_VARIANCE = 20000


class Star:
    D = 1000

    def __init__(self, scene):
        path = QPainterPath()

        #path.addRect(-10, -10, 20, 20)

        polygon = QPolygonF()
        polygon.append(QtCore.QPointF(13, 0))
        polygon.append(QtCore.QPointF(10, -5))
        polygon.append(QtCore.QPointF(10, -10))
        polygon.append(QtCore.QPointF(5, -10))
        polygon.append(QtCore.QPointF(0, -13))
        polygon.append(QtCore.QPointF(-5, -10))
        polygon.append(QtCore.QPointF(-10, -10))
        polygon.append(QtCore.QPointF(-10, -5))
        polygon.append(QtCore.QPointF(-13, 0))
        polygon.append(QtCore.QPointF(-10, 5))
        polygon.append(QtCore.QPointF(-10, 10))
        polygon.append(QtCore.QPointF(-5, 10))
        polygon.append(QtCore.QPointF(0, 13))
        polygon.append(QtCore.QPointF(5, 10))
        polygon.append(QtCore.QPointF(10, 10))
        polygon.append(QtCore.QPointF(10, 5))

        path.addPolygon(polygon)

        self._x, self._y = random.random() * 20000 - 10000, random.random() * 20000 - 10000
        self._z = random.random() * 20000 + MIN_DISTANCE
        self._speed = random.random() * SPEED
        self._path = scene.addPath(path)
        self._path.setBrush(QtCore.Qt.white)
        self.update(0)  # force placement

    def update(self, elapsed):

        self._z -= elapsed * self._speed
        if self._z < 0:
            self._z = random.random() * DISTANCE_VARIANCE + MIN_DISTANCE
        self._path.setX(self._x * self.D / self._z)
        self._path.setY(self._y * self.D / self._z)
        self._path.setScale(1 - self._z / (MIN_DISTANCE + DISTANCE_VARIANCE)) # Skalierung
        self._path.setRotation(self._path.rotation() + elapsed * 360) # Drehung
        return [self]

class StarSpawner:
    STARS_PER_SECOND = 10
    TOTAL_STARS = 100

    def __init__(self, scene):
        self._star_spawn_period = 1.0 / self.STARS_PER_SECOND
        self._accu = 0.0
        self._count = self.TOTAL_STARS
        self._scene = scene


    def update(self, elapsed):

        self._accu += elapsed
        spawned_stars = []
        while self._accu > self._star_spawn_period:
            spawned_stars.append(Star(self._scene))
            self._accu -= self._star_spawn_period

        self._count -= len(spawned_stars)

        if self._count > 0:
            spawned_stars.append(self)

        return spawned_stars


class GraphicsWindow(QGraphicsView):

    def __init__(self, parent=None):

        super(GraphicsWindow, self).__init__(parent)
        self._last = time.monotonic()
        scene = QGraphicsScene(self)
        self.setScene(scene)
        self.setBackgroundBrush(QtCore.Qt.black)
        self._things = [StarSpawner(scene)]
        scene.setSceneRect(-400, -400, 800, 800)

        self._timer = QtCore.QTimer(self)
        self._timer.setSingleShot(False)
        self._timer.setInterval(1000 / 60)
        self._timer.timeout.connect(self._update_all)
        self._timer.start()

    def _update_all(self):

        now = time.monotonic()
        elapsed = now - self._last
        self._last = now

        things_for_this_frame = self._things
        self._things = [] # neu!
        for thing in things_for_this_frame:
            print(things_for_this_frame)
            self._things.extend(thing.update(elapsed))


def main():
    app = QApplication(sys.argv)
    graphics_window = GraphicsWindow()
    graphics_window.show()
    sys.exit(app.exec_())

if __name__ == '__main__':
    main()
Gruß
Atalanttore
__deets__
User
Beiträge: 14494
Registriert: Mittwoch 14. Oktober 2015, 14:29

Ich kann das im Moment nicht selbst ueberpruefen. Aber weil ich gestern fuer ein Projekt das hier gefunden habe

https://github.com/pyqtgraph/pyqtgraph

ist das vielleicht etwas, wo du viel Python-Code findest, der QGraphicsView findest, an dem du dich langhangeln kannst.
Atalanttore
User
Beiträge: 407
Registriert: Freitag 6. August 2010, 17:03

@__deets__: Ganz schön viel Code. Wo beginnt da ein erfahrener Programmierer mit dem Entlanghangeln?

Mittlerweile habe ich nicht nur eine, sondern zwei Lösungen für das Problem gefunden. Siehe hier.

Gruß
Atalanttore
__deets__
User
Beiträge: 14494
Registriert: Mittwoch 14. Oktober 2015, 14:29

Einfach querlesen. Was dein Anfang ist kann ich dir nicht sagen. Das Ding hat Beispiele, wenn du darin etwas siehst, dass dir gefällt, schau dir die Klassen etc an p, die benutzt werden.
Antworten