zweites Fenster öffnen - mit loadUi

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

Ja. Es ist ein Signal. Wie bei jedem Button.
Crypto-Alman
User
Beiträge: 34
Registriert: Montag 23. Mai 2022, 20:26

Hey Zusammen,

ich habe weiter im Netz geschaut und folgende Lösung gefunden:

Code: Alles auswählen

        self.label = self.findChild(QLabel, "label_ForgotPassword")
        self.label.mousePressEvent = self.openCreateUserWindow

    def openCreateUserWindow(self, event):
        self.CreateUserWindow = GUICreateUser()
        self.CreateUserWindow.show()
Das klappt bedingt, ich vermute das event jeglicher Maustastendruck bedeudetet, da egal ob ich mit dem Mausrad, die Linke oder die rechte Maustaste auf das Label klicke, wird openCreateUserWindow ausgeführt. War das mit event gemeint und kann ich das noch weiter einschränken (nur Linksklicks Bspw.)?
Benutzeravatar
__blackjack__
User
Beiträge: 13004
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Crypto-Alman: `QLabel`-Objekte haben ein `linkActivated`-Signal, das heisst `linkActivated`. Und das `findChild()` unnötig umständlich ist, hatte ich doch auch schon geschrieben. Auf den Button greifst Du doch auch nicht so zu.
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
Crypto-Alman
User
Beiträge: 34
Registriert: Montag 23. Mai 2022, 20:26

@__blackjack__ Wie spreche ich aber mein QLabel an? Beziehungswiese wie kann ich darauf zugreifen, wenn ich nicht in der .py Datei arbeite. Ich kenne bisher nur findChild um mit einem Objekt wenn ich über den weg loadUi gehe weiterzuarbeiten. Wenn ich es so nenne, wie das Label in dem Fenster heißt klappt es nicht, auch mit findChild habe ich es probiert, klappt trotzdem nicht.

Danke :)

Code: Alles auswählen

from PyQt5.QtWidgets import QMainWindow, QApplication, QLabel, QLineEdit, QShortcut, QDialog, QWidget
from PyQt5.QtGui import QKeySequence
from PyQt5 import uic, QtWidgets, QtCore, Qt
import sys
import ressource


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

        # Lade die .ui Datei
        uic.loadUi("willkommen.ui", self)
        # Setzte das Fenster im Fullscreen Modus
        self.showFullScreen()
        # Definiere einen Shortcut um das Fenster in die Maximized Modus zu setzten
        self.maxiMode = QShortcut(QKeySequence("Ctrl+Q"), self)
        self.maxiMode.activated.connect(self.showMaximized)
        self.button_Login.clicked.connect(self.openCreateUserWindow)

        #self.label = self.findChild(QLabel, "label_ForgotPassword")
        #self.label.mouseReleaseEvent = self.openCreateUserWindow

        self.label_ForgotPassword.linkActivated.connect(self.openCreateUserWindow)

    def openCreateUserWindow(self):
        self.CreateUserWindow = GUICreateUser()
        self.CreateUserWindow.show()

class GUICreateUser(QWidget):
    def __init__(self):
        super(GUICreateUser, self).__init__()
        uic.loadUi("newuser.ui", self)

# Initialisiere/starte die App
app = QApplication(sys.argv)
GUIWindow = GUI()
GUIWindow.show()
app.exec_()
Benutzeravatar
__blackjack__
User
Beiträge: 13004
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Crypto-Alman: Was heisst ”klappt nicht”? Entweder Du bekommst einen `AttributeError`, dann heisst das im Designer nicht `label_ForgotPassword`, oder es passiert gar nichts, dann ist da kein Link auf dem Label, oder Du bekommst eine Ausnahme weil `openCreateUserWindow()` mit einem Argument zu viel aufgerufen wurde, denn `linkActivated` hat einen Parameter, den man natürlich im Slot auch erwarten muss, auch wenn man den Wert dann ignoriert.
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
Crypto-Alman
User
Beiträge: 34
Registriert: Montag 23. Mai 2022, 20:26

Hey blackjack, es passiert garnichts. Ich bekomme weder einen Error noch wird irgendetwas ausgeführt. Ich habe zum testen einfach mal print in die Funktion geschrieben und in der Konsole erscheint kein Text beim klick auf das Label. Wie bekomme ich den Link auf das Label?
Crypto-Alman
User
Beiträge: 34
Registriert: Montag 23. Mai 2022, 20:26

Hallo Zusammen,

ich komme mit dem Thema linkActivated leider nicht weiter.
Ich habe mir im Netz einige Codebeispiele angeschaut und versucht diese bei mir einzubauen, leider ohne Erfolg.

Ich habe zum testen folgenden Code in eine neue Datei gepackt:

Code: Alles auswählen

import sys
from PyQt5.QtWidgets import QVBoxLayout,QMainWindow,QApplication,QLabel,QWidget
from PyQt5.QtGui import QPixmap, QPalette
from PyQt5.QtCore import Qt

class QLabelDemo(QWidget) :
    def __init__(self):
        super().__init__()
        self.initUI()

    def initUI(self):
        label1 = QLabel(self)
        label2 = QLabel(self)
        label3 = QLabel(self)
        label4 = QLabel(self)

        label1.setText("<font color=yellow>PythonPyQt.com</font>")
        label1.setAutoFillBackground(True)
        palette = QPalette()
        palette.setColor(QPalette.Window,Qt.blue)
        label1.setPalette(palette)
        label1.setAlignment(Qt.AlignCenter)

        label2.setText("<a href='#'>QLabel2</a>")

        label3.setAlignment(Qt.AlignCenter)
        label3.setToolTip('Hint')
        label3.setPixmap(QPixmap("python.png"))

        label4.setOpenExternalLinks(True)
        label4.setText("https://python.org")
        label4.setAlignment(Qt.AlignCenter)
        label4.setToolTip('Python.org')

        vbox = QVBoxLayout()

        vbox.addWidget(label1)
        vbox.addWidget(label2)
        vbox.addWidget(label3)
        vbox.addWidget(label4)

        label2.linkHovered.connect(self.linkHovered)
        label4.linkActivated.connect(self.linkClicked)

        self.setLayout(vbox)
        self.setWindowTitle('QLabel Example')

    def linkHovered(self):
        print('Link hovered')

    def linkClicked(self):
        print('Link clicked')

if __name__ == '__main__':
    app = QApplication(sys.argv)
    main = QLabelDemo()
    main.show()
    sys.exit(app.exec_())
Auch dieser Code funkioniert nicht einwandfrei, wenn ich mit dem Mauszeiger über das Label fahre wird "Link hovered" in der Konsole angezeigt wenn ich jedoch auf das andere Label klicke wird zwar Python.org aufgerufen aber es wird kein "Link clicked" ausgegeben.

Habe es trotzdem nochmal versucht in meinen Code einzubauen, aber es funktioniert nicht, bei mir im Code funktioniert nichtmal hovered was beim anderen geklappt hat:

Code: Alles auswählen

from PyQt5.QtWidgets import QMainWindow, QApplication, QLabel, QLineEdit, QShortcut, QDialog, QWidget
from PyQt5.QtGui import QKeySequence
from PyQt5 import uic, QtWidgets, QtCore, Qt
import sys
import ressource
from clickablelabel import QLabelClickable

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

        # Lade die .ui Datei
        uic.loadUi("willkommen.ui", self)
        # Setzte das Fenster im Fullscreen Modus
        self.showFullScreen()
        # Definiere einen Shortcut um das Fenster in die Maximized Modus zu setzten
        self.maxiMode = QShortcut(QKeySequence("Ctrl+Q"), self)
        self.maxiMode.activated.connect(self.showMaximized)
        self.button_Login.clicked.connect(self.openCreateUserWindow)

        self.label_ForgotPassword.setOpenExternalLinks(True)
        self.label_ForgotPassword.linkActivated.connect(self.linkActivated)

    def linkActivated(self):
        print('Link active')

    def openCreateUserWindow(self):
        self.CreateUserWindow = GUICreateUser()
        self.CreateUserWindow.show()


class GUICreateUser(QWidget):
    def __init__(self):
        super(GUICreateUser, self).__init__()
        uic.loadUi("newuser.ui", self)


# Initialisiere/starte die App
app = QApplication(sys.argv)
GUIWindow = GUI()
GUIWindow.show()
app.exec_()
Jemand eine Idee? Bin euch echt dankbar. Lg Jan :)
__deets__
User
Beiträge: 14493
Registriert: Mittwoch 14. Oktober 2015, 14:29

Laut https://doc.qt.io/qt-5/qlabel.html#open ... Links-prop ist das ein steuerbares Verhalten. Würde ich mal mit rumspielen.
Benutzeravatar
__blackjack__
User
Beiträge: 13004
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Und noch mal: `linkActivated` ist ein Signal das einen Paramter hat. Den muss der Slot auch haben, sonst kann er ja nicht aufgerufen werden.

Minimaler Testfall der bei mir "#test" auf der Konsole ausgibt, wenn man auf den Link klickt:

Code: Alles auswählen

#!/usr/bin/env python3
import sys

from PyQt5.QtWidgets import QApplication, QLabel, QVBoxLayout, QWidget


def main():
    application = QApplication(sys.argv)
    window = QWidget()
    layout = QVBoxLayout()
    layout.addWidget(
        QLabel("<a href='#test'>This is a link</a>", linkActivated=print)
    )
    window.setLayout(layout)
    window.show()
    sys.exit(application.exec())


if __name__ == "__main__":
    main()
Edit: Und auch ein Designer-Minimalbeispiel funktioniert bei so. Die ui-Datei:

Code: Alles auswählen

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>Form</class>
 <widget class="QWidget" name="Form">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>102</width>
    <height>29</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>Form</string>
  </property>
  <layout class="QVBoxLayout" name="verticalLayout">
   <item>
    <widget class="QLabel" name="label">
     <property name="text">
      <string>&lt;a href=&quot;#test&quot;&gt;This is a link&lt;/a&gt;</string>
     </property>
    </widget>
   </item>
  </layout>
 </widget>
 <resources/>
 <connections/>
</ui>
Und das Programm dazu:

Code: Alles auswählen

#!/usr/bin/env python3
import sys

from PyQt5.QtWidgets import QApplication
from PyQt5.uic import loadUi


def main():
    application = QApplication(sys.argv)
    window = loadUi("test.ui")
    window.label.linkActivated.connect(print)
    window.show()
    sys.exit(application.exec())


if __name__ == "__main__":
    main()
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
Crypto-Alman
User
Beiträge: 34
Registriert: Montag 23. Mai 2022, 20:26

Hallo Zusammen,

vielen Dank für die Hilfe, ich habs geschafft, der Unterschied war, das ich das Label im Designer nicht zu einem Link gemacht habe (<a href='#test'>This is a link</a>)
Nachdem das Label im Designer zum Link gemacht habe, konnte ich drauf klicken und die Funktion wurde ausgeführt.

Vielen Dank für deine Beispiele, haben mir super geholfen <3
Crypto-Alman
User
Beiträge: 34
Registriert: Montag 23. Mai 2022, 20:26

Abschließende Frage zu dem Thema, kann ich die Farbe des blauen Links noch ändern? Anpassung der Style Sheets greifen nicht mehr.
Benutzeravatar
__blackjack__
User
Beiträge: 13004
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Crypto-Alman: Warum willst Du das machen? Ich wäre mit solchen Änderungen immer sehr vorsichtig, denn man weiss ja nicht was der Benutzer als Theme für Qt verwendet. Bei einigen Plattformen/Umgebungen benutzt Qt da auch systemweite Einstellungen. Im besten Fall änderst Du da was was sich der Benutzer ausgesucht hat, im schlechtesten Fall wird es unlesbar weil Deine Farbe zu nah an der Hintergrundfarbe ist.
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
Crypto-Alman
User
Beiträge: 34
Registriert: Montag 23. Mai 2022, 20:26

@__blackjack__ okay, danke für den Hinweis. Die Anwendung wird nur an meinem Rechner von anderen Menschen ausgeführt, sodass dies kein Problem sein sollte. Besteht denn grundsätzlich überhaupt die Möglichkeit?

EDIT: Hat geklappt mit "Formatierbaren Text bearbeiten.."
__deets__
User
Beiträge: 14493
Registriert: Mittwoch 14. Oktober 2015, 14:29

__blackjack__ hat geschrieben: Sonntag 29. Mai 2022, 13:17 Und noch mal: `linkActivated` ist ein Signal das einen Paramter hat. Den muss der Slot auch haben, sonst kann er ja nicht aufgerufen werden.
Das stimmt nicht. Man kann schon immer in Qt Slots ohne Argumente verwenden. Ob man auch nur einen Teil der Argumente benutzen kann, weiss ich nicht aus dem Kopf. Aber dein eigenes Beispiel, leicht umformuliert (Ich nutze Qt6):

Code: Alles auswählen

#!/usr/bin/env python3
import sys

from PyQt6.QtWidgets import QApplication, QLabel, QVBoxLayout, QWidget

def no_argument():
    print("no_argument")


def main():
    application = QApplication(sys.argv)
    window = QWidget()
    layout = QVBoxLayout()
    layout.addWidget(
        QLabel("<a href='#test'>This is a link</a>", linkActivated=no_argument)
    )
    window.setLayout(layout)
    window.show()
    sys.exit(application.exec())


if __name__ == "__main__":
    main()
Benutzeravatar
__blackjack__
User
Beiträge: 13004
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@__deets__: Ah, das wusste ich nicht. Cool. (Funktioniert auch bei PyQt5.)
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
Crypto-Alman
User
Beiträge: 34
Registriert: Montag 23. Mai 2022, 20:26

Guten Morgen @ __blackjack__ & __deets__ ,

ich wollte mich einmal bei euch für euren super Support bedanken, ihr habt mir in den letzten Tagen echt weitergeholfen und dank euch konnte ich einiges dazulernen und verstehen.
Es ist super als Laile gute Ansprechpartner zu haben, danke!

LG Jan
Antworten