Grafikproblem

Python und das Qt-Toolkit, erstellen von GUIs mittels des Qt-Designers.
Antworten
HeinKurz
User
Beiträge: 12
Registriert: Montag 20. März 2023, 22:09

Um die Grafikprogrammierung besser zu verstehen, wollte ich eine analoge Uhr programmieren. Dazu verwende ich auch einen Timer, der jede Sekunde das paintEvent aktiviert. Im paintEvent setze ich aber das Hintergrundbild (Ziffernblatt) neu (weil ich nicht weiß, wie man sonst das bereits gezeichnete wieder löscht), das wiederum löst ein paintEvent aus, was den Timer überschreibt, d.h. das Neuzeichnen erfolgt nicht jede Sekunde sondern viel öfter.
Hat jemand eine Idee wie man das löst ???

Code: Alles auswählen

import sys
import os
from datetime import *
import math
from random import *
from PyQt5.QtWidgets import QMainWindow, QApplication, QLabel, QMessageBox, QShortcut
from PyQt5.QtGui import (QIcon, QPixmap, QPainter, QColor, QFont, QFontMetrics, QBrush, QPen, QPolygonF, 
                         QKeySequence, QTransform)
from PyQt5.QtCore import Qt, QTimer, QTime, QRectF, QPointF


# background images
uhren = (["Uhr01.jpg", "Uhr02.jpg", "Uhr03.jpg", "Uhr04.jpg", "Uhr05.jpg", "UhrAlt.jpg", "UhrSimpsons.jpg",
          "UhrDig01.jpg", "UhrDig02.jpg", "UhrDig03bg.jpg", "UhrDomino.jpg", "UhrBraille.jpg", "UhrPendel01.jpg",
          "UhrPferd.jpg", "UhrSonnenuhr.jpg"])


class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()

        self.uhrnr = 0
        self.pixmap  = None

        # timer
        self.timer = QTimer(self)
        self.timer.timeout.connect(self.update)

        # main window
        self.setWindowTitle("Uhren I")
        self.setWindowIcon(QIcon("Uhren1.ico"))
        #self.setStyleSheet("background-image: url(./pic/Uhr001.jpg); background-repeat: no-repeat; background-position: center")
        self.label = QLabel()
        self.setCentralWidget(self.label)

        # keypress (next/prev clock)
        self.kleft  = QShortcut(QKeySequence("Left"), self)
        self.kleft.activated.connect(self.Prev)
        self.kdown  = QShortcut(QKeySequence("Down"), self)
        self.kdown.activated.connect(self.Prev)
        self.kright = QShortcut(QKeySequence("Right"), self)
        self.kright.activated.connect(self.Next)
        self.kup    = QShortcut(QKeySequence("Up"), self)
        self.kup.activated.connect(self.Next)

        self.Clock()


    def Prev(self):
        if self.uhrnr > 0:
            self.uhrnr -= 1
            self.Clock()


    def Next(self):
        if self.uhrnr < len(uhren) - 1:
            self.uhrnr += 1
            self.Clock()


    def Clock(self):
        # Basics
        self.timer.stop()
		# load background image
        fl = "./pic/{}".format(uhren[self.uhrnr])
        if not os.path.isfile(fl):
            return
        self.pixmap = QPixmap(fl)
        self.label.setPixmap(self.pixmap)
        self.setFixedSize(self.pixmap.size())
        # center window
        w1 = app.primaryScreen().size().width()
        h1 = app.primaryScreen().size().height()
        w2 = self.width()
        h2 = self.height()
        x = int((w1 - w2) / 2)
        y = int((h1 - h2) / 2)
        self.move(x, y)        
        self.timer.start(1000)


    def paintEvent(self, event):
        # drawing the hands

        dt = QTime.currentTime()
        self.setWindowTitle("Uhren I            {}".format(dt.toString()))
        s = dt.second() + dt.msec() / 1000
        m = dt.minute() + s / 60
        h = dt.hour()   + m / 60

        self.label.setPixmap(self.pixmap)           #  <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ?!?!?!?!?
        painter = QPainter(self.label.pixmap())
        painter.setRenderHint(QPainter.Antialiasing)
        ww = self.label.width()
        wh = self.label.height()

        if self.uhrnr == 0:   # clock 1 : shows only the (decimal) hour
            x0 = int(ww / 2)
            y0 = int(wh / 2)
            r  = int(ww / 2 * 0.8)
            hd = dt.hour() + dt.minute() / 60 + dt.second() / 3600
            w = math.pi / 6 * hd          # / 6 * h, / 30 * m, / 30 * s
            x1 = int(x0 + r * 0.8 * math.sin(w) + 0.5)
            y1 = int(y0 - r * 0.8 * math.cos(w) + 0.5)
            x2 = int(x0 + r * 1.1 * math.sin(w) + 0.5)
            y2 = int(y0 - r * 1.1 * math.cos(w) + 0.5)
            painter.drawLine(x1, y1, x2, y2)
            brush = QBrush(QColor(127, 127, 177, 100), Qt.SolidPattern)
            painter.setBrush(brush)
            pen = QPen(brush, 0, Qt.SolidLine, Qt.RoundCap)
            painter.setPen(pen)
            w = int(hd / 12 * 360 - 90) * -1
            painter.drawPie(x0 - r, y0 - r, r * 2, r * 2, w * 16 + 240, 360 * 16 - 480)
            painter.end()

        if self.uhrnr == 1:   # clock 2
		# ...


app = QApplication(sys.argv)
window = MainWindow()
window.show()
app.exec()

__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Statt das Label kannst du doch direkt ein QPixmap benutzen. Dann faellt das update via Label weg. Sollte zumindest, ausprobiert habe ich das nicht.
HeinKurz
User
Beiträge: 12
Registriert: Montag 20. März 2023, 22:09

__deets__ hat geschrieben: Samstag 27. April 2024, 10:56 Statt das Label kannst du doch direkt ein QPixmap benutzen. Dann faellt das update via Label weg. Sollte zumindest, ausprobiert habe ich das nicht.
Nö, funktioniert nicht, setCentralWidget kann kein QPixmap sein.
"setCentralWidget(self, widget: QWidget): argument 1 has unexpected type 'QPixmap'"
Antworten