Geometrische Objekte werden generiert, aber nicht angezeigt.

Python und das Qt-Toolkit, erstellen von GUIs mittels des Qt-Designers.
Antworten
Atalanttore
User
Beiträge: 157
Registriert: Freitag 6. August 2010, 17:03

Sonntag 2. Dezember 2018, 17:14

Hallo

Heute wollte ich mit Qt geometrische Formen zeichnen. Folgender Code zum Zeichnen eines Rechtecks funktioniert noch.

Rechteck.py:

Code: Alles auswählen

import sys
from PyQt5.QtWidgets import QApplication, QWidget
from PyQt5.QtGui import QPainter, QBrush, QPen
from PyQt5 import QtCore


class MainWindow(QWidget):

    def __init__(self, parent=None):
        QWidget.__init__(self)
        self.pen = QPen(QtCore.Qt.red) # Außenliniefarbe
        self.pen.setWidth(5) # Außenliniendicke
        self.brush = QBrush(QtCore.Qt.blue) # Füllfarbe


    def paintEvent(self, event):
        painter = QPainter(self)
        painter.setPen(self.pen)
        painter.setBrush(self.brush)
        painter.drawRect(50, 50, 200, 200)


def main():
    app = QApplication(sys.argv)
    main_window = MainWindow(app)
    main_window.show()
    sys.exit(app.exec_())


if __name__ == "__main__":
    main()

Im nächsten Schwierigkeitsgrad wollte ich dann Punktobjekte, die auf einer Kreisbahn angeordnet sind, mittels einer for-Schleife erstellen und zeichnen. Punktobjekte werden laut `print(points)` mit dem folgenden Code zwar erstellt, aber es erscheinen keine Punkte im `MainWindow`.

Punkte.py

Code: Alles auswählen

from PyQt5.QtWidgets import QWidget, QApplication
from PyQt5.QtGui import QPainter, QBrush
from PyQt5 import QtCore
import math
import sys

points = []

circle_points = 30
point_color = QtCore.Qt.red
point_diameter = 20
circle_diameter = 500


class MainWindow(QWidget):

    def __init__(self, parent=None):
        QWidget.__init__(self)
        self.setGeometry(0,0,800,800)
        for i in range(circle_points):
            angle = (360 / circle_points * i)
            point = Point(self, angle, point_color, point_diameter, circle_diameter)
            points.append(point)

        print(points)


class Point(QWidget):

    def __init__(self, main_window, angle, point_color, point_diameter, circle_diameter):
        super().__init__()
        self.main_window = main_window
        self.x_center = self.width() / 2
        self.y_center = self.height() / 2
        self.point_color = point_color
        self.point_diameter = point_diameter
        self.circle_diameter = circle_diameter
        self.angle = angle
        self.brush = QBrush(self.point_color)

    def paintEvent(self, event):
        painter = QPainter(self.main_window)
        painter.setBrush(self.brush)

        x = self.x_center + (self.circle_diameter / 2 * math.cos(math.radians(self.angle)))
        y = self.y_center + (self.circle_diameter / 2 * math.sin(math.radians(self.angle)))

        x1 = int(x - self.point_diameter)
        y1 = int(y - self.point_diameter)
        x2 = int(x + self.point_diameter)
        y2 = int(y + self.point_diameter)
        print("Test")

        painter.drawEllipse(x1, y1, x2, y2)


def main():
    app = QApplication(sys.argv)
    main_window = MainWindow(app)
    main_window.show()
    sys.exit(app.exec_())


if __name__ == "__main__":
    main()
  1. Die Anweisung `print("Test")` wird gar nicht ausgeführt. Wo liegt der oder die Fehler?
  2. Warum braucht man zum Zeichnen eigentlich die Methode `paintEvent(self, event)`? Von den über Google gefundenen Erklärungen habe ich nur verstanden, dass damit wohl die Methode `paintEvent` der Klasse `QWidget` überschrieben wird.
Gruß
Atalanttore
__deets__
User
Beiträge: 4016
Registriert: Mittwoch 14. Oktober 2015, 14:29

Sonntag 2. Dezember 2018, 17:20

Da ist vieles im argen.

- Du benutzt widgets. Die wollen ziemlich sicher ueber ihre parent-Eigenschaft miteinander verbunden werden. Du uebergibst aber kein parent. Das widget haengt also "im leeren". Und das, obwohl du schon main_window mit reinreichst. Und darum wird wohl auch dein print nicht aufgerufen
- widgets sind nicht gedacht fuer so etwas. Die sind per Definition immer rechteckig, und eine Art Spielfeld oder Grafik daraus aufzubauen ist ungewoehnlich bis unmoeglich. Wenn du viele graphische Objekte darstellen willst, schau dir den QGraphicsView an, der ist dazu gedacht.
- das das mainwindow sich seine geometry selbst setzt macht es als allgemeines Objekt unnutzbar. Das sollte eigentlich gar nicht, bestenfalls von aussen, geschehen.
Atalanttore
User
Beiträge: 157
Registriert: Freitag 6. August 2010, 17:03

Sonntag 2. Dezember 2018, 21:28

@__deets__: Soweit ich deine Vorschläge verstanden habe und mithilfe des Codebeispiels hier habe ich den Code jetzt umgebaut (siehe unten). Leider werden auch mit dem umgebauten Code noch keine Punkte gezeichnet. Als Fehlermeldung erscheint nun `QPainter::setBrush: Painter not active` in der Konsole.

__deets__ hat geschrieben:
Sonntag 2. Dezember 2018, 17:20
- Du benutzt widgets. Die wollen ziemlich sicher ueber ihre parent-Eigenschaft miteinander verbunden werden. Du uebergibst aber kein parent. Das widget haengt also "im leeren". Und das, obwohl du schon main_window mit reinreichst. Und darum wird wohl auch dein print nicht aufgerufen
Ein `parent` wird jetzt übergeben und `print("Test")` wird aufgerufen.


__deets__ hat geschrieben:
Sonntag 2. Dezember 2018, 17:20
- widgets sind nicht gedacht fuer so etwas. Die sind per Definition immer rechteckig, und eine Art Spielfeld oder Grafik daraus aufzubauen ist ungewoehnlich bis unmoeglich. Wenn du viele graphische Objekte darstellen willst, schau dir den QGraphicsView an, der ist dazu gedacht.
- das das mainwindow sich seine geometry selbst setzt macht es als allgemeines Objekt unnutzbar. Das sollte eigentlich gar nicht, bestenfalls von aussen, geschehen.
`MainWindow()` wurde zu `GraphicsWindow()` und erbt von `QGraphicsView`. Hat sich damit auch das Problem mit der `geometry` gelöst?


Der umgebaute Code:

Code: Alles auswählen

from PyQt5.QtCore import QRectF
from PyQt5 import QtCore

from PyQt5.QtWidgets import QApplication, QGraphicsView, QGraphicsScene, QGraphicsItem
from PyQt5.QtGui import QPainter, QBrush
import math

points = []

circle_points = 30
point_color = QtCore.Qt.red
point_diameter = 20
circle_diameter = 500


class Point(QGraphicsItem):
    def __init__(self, angle, point_color, point_diameter, circle_diameter, x_center, y_center):
        super(Point, self).__init__()
        self.x_center = x_center
        self.y_center = y_center
        self.point_color = point_color
        self.point_diameter = point_diameter
        self.circle_diameter = circle_diameter
        self.angle = angle
        self.brush = QBrush(self.point_color)


    def paint(self, painter, option, widget):
        painter = QPainter()
        painter.setBrush(self.brush)

        x = self.x_center + (self.circle_diameter / 2 * math.cos(math.radians(self.angle)))
        y = self.y_center + (self.circle_diameter / 2 * math.sin(math.radians(self.angle)))

        x1 = int(x - self.point_diameter)
        y1 = int(y - self.point_diameter)
        x2 = int(x + self.point_diameter)
        y2 = int(y + self.point_diameter)
        print("Test")

        painter.drawEllipse(x1, y1, x2, y2)


    def boundingRect(self):
        return QRectF(0,0,800,800)


class GraphicsWindow(QGraphicsView):
    def __init__(self, parent=None):
        super(GraphicsWindow, self).__init__(parent)
        scene = QGraphicsScene(self)
        self.x_center = self.width() / 2
        self.y_center = self.height() / 2

        for i in range(circle_points):
            angle = (360 / circle_points * i)
            point = Point(angle, point_color, point_diameter, circle_diameter, self.x_center, self.y_center)
            points.append(point)
            scene.addItem(point)

        scene.setSceneRect(0, 0, 800, 800)
        self.setScene(scene)
        self.setCacheMode(QGraphicsView.CacheBackground)


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

if __name__ == '__main__':
    main()
Bei der Methode `paint()` in der Klasse `Point(QGraphicsItem)` bemäkelt meine IDE (PyCharm) folgendes:

Code: Alles auswählen

Signature of method 'Point.paint()' does not match signature of base method in class 'QGraphicsItem'
This inspection detects inconsistencies in overriding method signatures.
In der Doku zu `paint()` werden aber genauso `painter`, `option` und `widget` als formale Parameter genannt. Was ist hier mit Signatur gemeint?

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

Sonntag 2. Dezember 2018, 21:48

Ich würde erstmal mit den eingebauten Items spielen, bevor ich ein eigenes erstellen würde. Ggf reichen die schon völlig aus.

Das geometry Ding hat ja was mit der Position und Dimension des Fensters selbst zu tun. Das Scene rect legt hingegen die Koordinaten der dargestellten Items fest - das wird dann umtransformiert. Das ist ja was komplett anderes.

Mein Punkt richtet sich gegen ersteres: entweder man bietet einen fullscreen Modus an, den der User wieder verlassen kann. Oder der User positioniert das Fenster selbst. Das vorzugeben ist ein usability-no-no. Du könntest die letzte Position dir merken und restaurieren. Das wäre ok.
__deets__
User
Beiträge: 4016
Registriert: Mittwoch 14. Oktober 2015, 14:29

Sonntag 2. Dezember 2018, 22:18

Achso: warum pycharm da bockig ist - kA. Ich benutze das nicht, aber generell ist Typinferenz in Python schwierig. Das kann schon mal sein, dass das nicht klappt. Wenn der Code tut, kann es so falsch nicht sein.
Atalanttore
User
Beiträge: 157
Registriert: Freitag 6. August 2010, 17:03

Montag 3. Dezember 2018, 22:53

Ich habe jetzt `QGraphicsItem` durch `QGraphicsEllipseItem` (QGraphicsEllipseItem → QAbstractGraphicsShapeItem → QGraphicsItem) ersetzt. Die Methode `setRect()` habe ich dann auch mal benutzt. Leider wird nach wie vor nichts gezeichnet und es erscheint immer noch folgende Fehlermeldung in Konsole:

Code: Alles auswählen

QPainter::setBrush: Painter not active

Code:

Code: Alles auswählen

from PyQt5.QtCore import QRectF
from PyQt5 import QtCore

from PyQt5.QtWidgets import QApplication, QGraphicsView, QGraphicsScene, QGraphicsEllipseItem
from PyQt5.QtGui import QPainter, QBrush
import math

points = []

circle_points = 30
point_color = QtCore.Qt.red
point_diameter = 20
circle_diameter = 500



class Point(QGraphicsEllipseItem):
    def __init__(self, angle, point_color, point_diameter, circle_diameter, x_center, y_center):
        super(Point, self).__init__()
        self.x_center = x_center
        self.y_center = y_center
        self.point_color = point_color
        self.point_diameter = point_diameter
        self.circle_diameter = circle_diameter
        self.angle = angle
        self.brush = QBrush(self.point_color)


    def paint(self, painter, option, widget):
        painter = QPainter()
        painter.setBrush(self.brush)

        x = self.x_center + (self.circle_diameter / 2 * math.cos(math.radians(self.angle)))
        y = self.y_center + (self.circle_diameter / 2 * math.sin(math.radians(self.angle)))

        x1 = int(x - self.point_diameter)
        y1 = int(y - self.point_diameter)
        x2 = int(x + self.point_diameter)
        y2 = int(y + self.point_diameter)

        self.setRect(x1, y1, x2, y2)
        painter.drawEllipse(x1, y1, x2, y2)
        print("Ich werde auch ausgeführt :-)")

    def boundingRect(self):
        return QRectF(0,0,800,800)


class GraphicsWindow(QGraphicsView):
    def __init__(self, parent=None):
        super(GraphicsWindow, self).__init__(parent)
        scene = QGraphicsScene(self)
        self.x_center = self.width() / 2
        self.y_center = self.height() / 2

        for i in range(circle_points):
            angle = (360 / circle_points * i)
            point = Point(angle, point_color, point_diameter, circle_diameter, self.x_center, self.y_center)

            points.append(point)
            scene.addItem(point)

        scene.setSceneRect(0, 0, 800, 800)
        self.setScene(scene)
        self.setCacheMode(QGraphicsView.CacheBackground)


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

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

Mittwoch 5. Dezember 2018, 21:56

So, ich habe damit mal ein bisschen rumgespielt. Du warst schon fast da, aber der entscheidende Fehler ist mir auch erst gerade aufgefallen: du baust einen eigenen Painter. Der haengt in der Luft, tut nichts und kann nichts. Du musst stattdessen einfach nur den uebergebenen nehmen, das war's.

Code: Alles auswählen

from PyQt5.QtCore import QRectF
from PyQt5 import QtCore

from PyQt5.QtWidgets import QApplication, QGraphicsView, QGraphicsScene, QGraphicsEllipseItem
from PyQt5.QtGui import QPainter, QBrush
import math

points = []

circle_points = 30
point_color = QtCore.Qt.red
point_diameter = 20
circle_diameter = 500

class Point(QGraphicsEllipseItem):
    def __init__(self, angle, point_color, point_diameter, circle_diameter, x_center, y_center):
        super(Point, self).__init__()
        self.x_center = x_center
        self.y_center = y_center
        self.point_color = point_color
        self.point_diameter = point_diameter
        self.circle_diameter = circle_diameter
        self.angle = angle
        self.brush = QBrush(self.point_color)


    def paint(self, painter, option, widget):
        painter.setBrush(self.brush)

        x = self.x_center + (self.circle_diameter / 2 * math.cos(math.radians(self.angle)))
        y = self.y_center + (self.circle_diameter / 2 * math.sin(math.radians(self.angle)))

        x1 = int(x - self.point_diameter)
        y1 = int(y - self.point_diameter)
        x2 = int(x + self.point_diameter)
        y2 = int(y + self.point_diameter)

        self.setRect(x1, y1, x2, y2)
        painter.drawEllipse(x1, y1, x2, y2)
        print("Ich werde auch ausgeführt :-)")

    def boundingRect(self):
        return QRectF(0,0,800,800)


class GraphicsWindow(QGraphicsView):
    def __init__(self, parent=None):
        super(GraphicsWindow, self).__init__(parent)
        scene = QGraphicsScene(self)
        self.setScene(scene)
        self.x_center = self.width() / 2
        self.y_center = self.height() / 2

        for i in range(circle_points):
            angle = (360 / circle_points * i)
            scene.addRect(QRectF(i * 20, i * 20, 20, 20), QtCore.Qt.red )
            ellipse = QGraphicsEllipseItem((i + 1) * 20, i * 20, 20, 20)
            scene.addItem(ellipse)
            point = Point(angle, point_color, point_diameter, circle_diameter, self.x_center, self.y_center)
            scene.addItem(point)

        scene.setSceneRect(0, 0, 800, 800)
        self.setCacheMode(QGraphicsView.CacheBackground)


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

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

Mittwoch 5. Dezember 2018, 21:59

Nachtrag: die bounding box ist natuerlich auch komplett falsch. Die muss schon die wirklichen Koordinaten und ausmasse des Items beruecksichtigen. Und da du ableitest, kannst du auch von QGraphicsItem ableiten. Das, was eine Ellipse ausmacht, benutzt du ja gar nicht. Mein Code tut das, wie man da den Pen/Brush setzt habe ich aber noch nicht rausgefummelt. Last but not least: leite NICHT ab, benutzt die addPath-Methode.
__deets__
User
Beiträge: 4016
Registriert: Mittwoch 14. Oktober 2015, 14:29

Mittwoch 5. Dezember 2018, 22:48

Und hier noch ein Beispiel, welches illustriert, dass man nicht ableiten muss. Und welche Vorteile das Scene-Modell hat bei Koordinaten etc.

Code: Alles auswählen

import random
import time

from PyQt5.QtCore import QRectF
from PyQt5 import QtCore

from PyQt5.QtWidgets import QApplication, QGraphicsView, QGraphicsScene
from PyQt5.QtGui import QPainter, QBrush, QPainterPath

points = []

SPEED = 5000
MIN_DISTANCE = 30000
DISTANCE_VARIANCE = 20000


class Star:
    D = 1000

    def __init__(self, scene):
        path = QPainterPath()
        path.addRect(-10, -10, 20, 20)
        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.setPen(QtCore.Qt.red)

    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))
        self._path.setRotation(self._path.rotation() + elapsed * 360)


class GraphicsWindow(QGraphicsView):

    def __init__(self, parent=None):
        super(GraphicsWindow, self).__init__(parent)
        self._last = time.monotonic()
        scene = QGraphicsScene(self)
        self.setScene(scene)
        self.x_center = self.width() / 2
        self.y_center = self.height() / 2

        self._stars = []
        for i in range(100):
            self._stars.append(
                Star(scene)
            )
        scene.setSceneRect(-400, -400, 800, 800)

        self.setCacheMode(QGraphicsView.CacheBackground)
        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
        for star in self._stars:
            star.update(elapsed)


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

if __name__ == '__main__':
    main()
Atalanttore
User
Beiträge: 157
Registriert: Freitag 6. August 2010, 17:03

Mittwoch 5. Dezember 2018, 22:51

@__deets__: Danke für den vielen Beispielcode. Mit dem Durcharbeiten werde ich einige Zeit beschäftigt sein.
Atalanttore
User
Beiträge: 157
Registriert: Freitag 6. August 2010, 17:03

Sonntag 9. Dezember 2018, 18:25

@__deets__: Ich habe mich jetzt mithilfe von Dokumentationen durchgearbeitet und mit deinem Beispielcode gespielt.

Meine Erkenntnisse und Fragen zu einzelnen Anweisungen habe ich mal als Kommentare im Beispielcode ergänzt.

Code: Alles auswählen

import random
import time

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

points = []

SPEED = 5000
MIN_DISTANCE = 30000
DISTANCE_VARIANCE = 20000


class Star:
    D = 1000 # Durchmesser?

    def __init__(self, scene):
        path = QPainterPath() # Pfad für Kontur erstellen
        path.addRect(-10, -10, 20, 20) # Kontur dem Stern zuweisen
        self._x, self._y = random.random() * 20000 - 10000, random.random() * 20000 - 10000 # Zufallskoordinaten für x und y berechnen
        self._z = random.random() * 20000 + MIN_DISTANCE # Zufallskoordinate für z berechnen
        self._speed = random.random() * SPEED # Zufallsgeschwindigkeit berechnen
        self._path = scene.addPath(path) # Pfad zur Szene hinzufügen
        self._path.setPen(QtCore.Qt.red) # Farbe der Außenlinie zuweisen

    def update(self, elapsed):
        self._z -= elapsed * self._speed # z-Koordinate neu berechnen
        if self._z < 0:
            self._z = random.random() * DISTANCE_VARIANCE + MIN_DISTANCE # Zufallszahl * Multiplikator + Mindestabstand
        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)) # Sterne bei der Bewegung nach vorne größer skalieren
        self._path.setRotation(self._path.rotation() + elapsed * 360) # Drehbewegung der Sterne


class GraphicsWindow(QGraphicsView):

    def __init__(self, parent=None):
        super(GraphicsWindow, self).__init__(parent) # Programm läuft auch, wenn man kein parent übergibt
        self._last = time.monotonic() # Letzte Zeit zuweisen
        scene = QGraphicsScene(self) # Szene erstellen
        self.setScene(scene) # QGraphicsScene dem GraphicsWindow zuweisen
        # self.x_center = self.width() / 2
        # self.y_center = self.height() / 2

        self._stars = []
        for i in range(100):
            self._stars.append(
                Star(scene) # 100 Star-Objekte erstellen und Liste hinzufügen
            )
        scene.setSceneRect(-400, -400, 800, 800) # Größe der Szene festlegen

        self.setCacheMode(QGraphicsView.CacheBackground) # ?
        self._timer = QtCore.QTimer(self) # QTimer-Objekt erstellen
        self._timer.setSingleShot(False) # Programm läuft auch ohne diese Anweisung
        self._timer.setInterval(1000 / 60) # Timer-Intervall festlegen
        self._timer.timeout.connect(self._update_all) # Aktualisierungsmethode aufrufen, wenn Timer abgelaufen ist.
        self._timer.start() # Timer neu starten

    def _update_all(self):
        now = time.monotonic() # Aktuelle Zeit zuweisen
        elapsed = now - self._last # Vergangene Zeit berechnen
        self._last = now # Letzte Zeit durch aktuelle Zeit ersetzen
        for star in self._stars:
            star.update(elapsed) # Aktualisierungsmethode jedes Star-Objektes mit vergangener Zeit aufrufen


def main():
    import sys # Warum hier unten importieren?
    app = QApplication(sys.argv)
    graphics_window = GraphicsWindow()
    graphics_window.show()
    sys.exit(app.exec_())

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

Sonntag 9. Dezember 2018, 19:45

Das mit dem sys in main musst du dich selbst fragen - von dir habe ich das ja ;) Ich habe das einfach uebernommen. Das ist so natuerlich Unsinn. Auch den Cache-Modus hast *du* eingefuehrt, keine Ahnung, was genau der bewirkt.

Und was deine Kommentare im allgemeinen angeht - die sind jetzt nicht so sinnvoll wie ich finde, denn sie sagen ja nur, was da steht. Zufallszahl * Multiplikator + Mindestabstand.
Viel interessanter waere zu sagen "bei negativem Z Stern wieder in der Ferne erscheinen lassen". Denn darum geht es ja.



D ist kein Durchmesser, sondern eine Konstante fuer die Perspektivische Transformation. Ich hab das so aus dem Gedaechtnis gemacht. Da koennte man jetzt mal in ein Buch zur 3D-Programmierung gucken.
Atalanttore
User
Beiträge: 157
Registriert: Freitag 6. August 2010, 17:03

Sonntag 9. Dezember 2018, 20:43

@__deets__: Danke für die Antwort.
  1. Stammen die Formeln im Code alle aus einem Buch zur 3D-Programmierung?
  2. Ohne die folgenden Anweisungen läuft gar nichts mehr, aber was wird da eigentlich berechnet?

    Code: Alles auswählen

            self._path.setX(self._x * self.D / self._z)
            self._path.setY(self._y * self.D / self._z)
  3. Im Ausgabefenster erscheint sowohl ein horizontaler als auch ein vertikaler Scrollbalken. Kann man die Scrollbalken auch deaktivieren?
Gruß
Atalanttore
__deets__
User
Beiträge: 4016
Registriert: Mittwoch 14. Oktober 2015, 14:29

Sonntag 9. Dezember 2018, 21:42

1. nein, aus meinem Kopf. So habe ich das schon auf dem AMIGA in assembler gemacht. Und da hatte ich es ggf aus einer Zeitschrift.
2. Das ist die perspektivische Transformation.
3. Bestimmt, durch Eigenschaften des Widgets. Im Designer mit rumspielen, Doku lesen. Weil aus dem Kopf weiß ich das nicht.
Antworten