Προς το περιεχόμενο

Προτεινόμενες αναρτήσεις

Δημοσ.

Προσπαθώ να φτιάξω μια εφαρμογή για προσωπική χρήση σε python με χρήση του eric ΙDE σε linux. Έχω λοιπόν δύο παράθυρα ως τώρα, το κεντρικό mainwindow και ένα παράθυρο διαλόγου το optionsdialog. Και τα δύο έχουν δημιουργηθεί με το qt designer και έχουν αυτόματα δημιουργηθεί και τα αντίστοιχα αρχεία (Ui_mainwindow.py, mainwindow.py, Ui_optionsdialog.py, optionsdialog.py) από το eric. Τα αρχεία UI βρίσκονται στον υποφάκελο ui και τα άλλα στον κεντρικό φάκελο του project. Θέλω λοιπόν να χρησιμοποιήσω κάποια δεδομένα από το παράθυρο διαλόγου στο κεντρικό παράθυρο. Συγκεκριμένα, έχω μερικά radiobuttons και θέλω το κείμενο του κουμπιού που επιλέγεται να μεταφέρεται και ν' αλλάζει ένα label στο κεντρικό παράθυρο της εφαρμογής. Έχω ήδη κάνει import το παράθυρο διαλόγου στο κεντρικό παράθυρο:

from .optionsdialog import Dialog

....


def on_optionsButton_clicked(self):
        """
        Slot documentation goes here.
        """
        self.dlg=Dialog()
        self.dlg.show()

και μπορώ ν' ανοίξω το διάλογο μέσω το παραπάνω κουμπιού.

Ψάχνοντας βρήκα κάποιες σχετικές απαντήσεις για χρήση global μεταβλητής, αλλά το κεντρικό πρόβλημα που παρουσιάστηκε, είναι ότι δε μπορώ να κάνω import του κεντρικού παραθύρου στο παράθυρο διαλόγου. Έχω δοκιμάσει τα παρακάτω:

from .mainwindow import MainWindow
from mainwindow import MainWindow
from ui.mainwindow import MainWindow

Αλλά σε όλες τις περιπτώσεις εμφανίζεται το σφάλμα:

unhandled ImportError
"cannot import name 'MainWindow'"

με το ξεκίνημα της εφαρμογής.

Πως λοιπόν μπορώ να πάρω το κείμενο και να το χρησιμοποιήσω στο κεντρικό παράθυρο?

Έχετε υπ' όψην ότι η εμπειρία μου με python και pyqt είναι ελάχιστη και επίσης μικρή στον προγραμματισμό γενικότερα, μιας και ασχολούμαι περιστασιακά και για προσωπική χρήση. 

Δημοσ.

Σχετικά με τα imports αν δεν δούμε το directory structure είναι δύσκολο να απαντήσουμε. Αν και νομίζω ότι κινείσαι προς λάθος κατεύθυνση. Τα globals σπάνια είναι η ενδεδειγμένη λύση (χωρίς να σημαίνει ότι κάποιες φορές δεν είναι απαραίτητα). Anyway, αυτό το παράδειγμα πιστεύω θα σε ξεμπλοκάρει.

  • Like 1
Δημοσ.

Δεν θέλω σώνει και καλά να χρησιμοποιήσω globals, αυτό που θέλω είναι να χρησιμοποιήσω κείμενο από το ένα αρχείο/παράθυρο, στο άλλο. Απλά αυτό βρήκα που μου φάνηκε συναφές με αυτό που θέλω και προσπάθησα να το υλοποιήσω. Με λίγο περισσότερο ψάξιμο είδα πάντως ότι πιο ενδεδειγμένος τρόπος θεωρούνται τα signals, αλλά το μόνο σχετικό παράδειγμα που βρήκα ως τώρα κι εκεί δεν κατάφερα ως τώρα να το προσαρμόσω στον κώδικά μου.

Το παράδειγμα από το link που παρέθεσες δεν καταλαβαίνω πως θα με βοηθήσει όμως? Απ' ότι είδα αναφέρεται σε παραδείγματα διάφορων τύπων διαλόγου. Τους διαλόγους μπορώ να τους συνδέσω και εμφανίσω από το κεντρικό παράθυρο της εφαρμογής, καθώς και να ορίσω ενέργειες στα κουμπιά ή σε άλλα περιεχόμενα στοιχεία τους(τουλάχιστον ότι έχω χρειαστεί ως τώρα). Το πρόβλημα είναι πως θα συνδέσω διαφορετικούς διαλόγους/παράθυρα μεταξύ τους ώστε να είναι δυνατή η ανταλλαγή δεδομένων. Και πάνω σ' αυτό, δεν βλέπω να έχει κάτι ο σύνδεσμος που παρέθεσες. 

Δημοσ.

Disclaimer: Πάνε χρόνια από την τελευταία φορά που τα κοίταξα αυτά οπότε μπορεί να μη θυμάμαι σωστά όλες τις λεπτομέρειες + μπορεί να έχουν αλλάξει κάποια πράγματα με το Qt5

  1. Κάθε widget (πρέπει) να έχει ένα parent https://stackoverflow.com/questions/35782474/pyqt-parent-for-widgets-necessary
  2. Στην κορυφή της ιεραρχίας βρίσκεται το main window και όλα τα widgets είναι παιδιά/εγγόνια/δισέγγονα/κτλ
  3. Τον «γονιό» του κάθε widget μπορείς να τον βρεις με self.parent
  4. Tον «παππού» μπορείς να τον βρείς με self.parent.parent
  5. Τα παιδιά του κάθε widget μπορείς να τα βρεις και με μια μέθοδο (findChildren???) αν και αυτό που συνήθως κάνεις είναι να αποθηκεύσεις ένα reference του child στον parent. Πχ αν είσαι στο main window θα αποθηκεύσεις δύο comboboxes ως
    self.combo1 = QComboBox(self)
    self.combo2 = QComboBox(self)

    Κρατάς δηλαδή references για κάθε widget που θα χρειαστείς.

  6. Γενικά, αν χρειαστείς δηλαδή να πάρεις στοιχεία από το custom_widget του parent σου κάνεις

    self.parent.custom_widget.<get_method>()
  7. Αν πάλι χρειαστείς το αντίστροφο, δηλαδή μέσα από τον parent χρειαστείς τα δεδομένα του custom_widget του child σου, τότε κάνεις:
    self.child.custom_widget.<get_method>()

    (το child είναι το όνομα του attribute στο οποίο έχεις αποθηκεύσει το reference του child widget.)

 

Αν διαβάσεις προσεκτικά το πρώτο snippet στο link που σου έδωσα, θα δεις ότι ανανεώνει το value ενός widget στο Main Window βάσει της τιμής ενός dialog:

    def showDialog(self):
        text, ok = QInputDialog.getText(self, 'Input Dialog', 'Enter your name:')
        if ok:
            self.le.setText(str(text))    # <--- This is it!

Σκέψου ότι αντί για self.le θα μπορούσε να είχε self.parent.le κτλ

Δημοσ.

Κατ' αρχήν ευχαριστώ για τον κόπο που έκανες να αναλύσεις τα παραπάνω.

Παρότι είναι αρκετά διαφωτιστικά, ή δεν έχω καταλάβει ακόμη πως λειτουργούν(αρκετά πιθανό αυτό 😂), ή κάτι ακόμη χρειάζεται, λόγω του τρόπου που δημιουργούνται και συνδέονται μεταξύ τους τα widgets μέσω του qt designer και του eric. Όλες οι φόρμες(παράθυρα, διάλογοι κλπ) έχουν ως "def __init__(self, parent=None)" , ενώ στη main(που είναι ένα ξεχωριστό αρχείο για την εκκίνηση του κεντρικού παραθύρου της εφαρμογής) υπάρχουν τα παρακάτω:

from PyQt5 import QtWidgets
from ui.mainwindow import MainWindow

if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)
    app.setQuitOnLastWindowClosed(False)
    ui = MainWindow()
    ui.show()
    sys.exit(app.exec_()

Αφού λοιπόν δεν έχει οριστεί ένα παράθυρο ως parent, μήπως και τα δύο είναι ανεξάρτητα μεταξύ τους και επομένως χρειάζεται κάπως να οριστεί κάποια από αυτά ως γονικό? Ή αυτόματα το παράθυρο διαλόγου(Qdialog) είναι child του κεντρικού παραθύρου?

Μήπως χρειάζεται να οριστούν κάπως στον παραπάνω κώδικα, ή κάπου αλλού?

 

Δημοσ. (επεξεργασμένο)

Είναι δική σου απόφαση βέβαια, αλλά εγώ στη θέση σου, τουλάχιστον μέχρι να αποκτούσα καλύτερη κατανόηση του τι γίνεται και γιατί, θα σταματούσα να χρησιμοποιώ το Qt Designer. Αν μη τι άλλο, το να γράψεις το UI με κώδικα είναι διδακτικό και στην πράξη δεν είναι και τόσο χρονοβόρο (αν έχεις αποφασίσει πως θες να είναι το design).

IMHO εργαλεία σαν το Qt Designer έχουν νόημα μόνο αν ήδη γνωρίζεις πολύ καλά τις βιβλιοθήκες που χρησιμοποιείς + αν η δουλειά σου είναι να φτιάχνεις GUI όλη μέρα.

Επεξ/σία από pmav99
Δημοσ.

Απαντάω με καθυστέρηση, ότι το πρόβλημα έχει λυθεί, με τη χρήση του "parent".

Ήταν αρκετά απλό τελικά. Έπρεπε να γίνουν τα παρακάτω, επειδή όλες οι φόρμες που δημιουργεί το qt designer έχουν  parent=None:

Μία αλλαγή στην __init__

def __init__(self, parent):

και ορισμός στην __init__ :

self.parent=parent

Έπειτα είναι δυνατή η χρήση των widgets με το "self.parent.<ονομα_widget>.method" όπως ανέφερε ο @pmav99

 

Δημιουργήστε ένα λογαριασμό ή συνδεθείτε για να σχολιάσετε

Πρέπει να είστε μέλος για να αφήσετε σχόλιο

Δημιουργία λογαριασμού

Εγγραφείτε με νέο λογαριασμό στην κοινότητα μας. Είναι πανεύκολο!

Δημιουργία νέου λογαριασμού

Σύνδεση

Έχετε ήδη λογαριασμό; Συνδεθείτε εδώ.

Συνδεθείτε τώρα
  • Δημιουργία νέου...