dancer_69 Δημοσ. 23 Οκτωβρίου 2018 Δημοσ. 23 Οκτωβρίου 2018 Προσπαθώ να φτιάξω μια εφαρμογή για προσωπική χρήση σε 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 είναι ελάχιστη και επίσης μικρή στον προγραμματισμό γενικότερα, μιας και ασχολούμαι περιστασιακά και για προσωπική χρήση.
pmav99 Δημοσ. 23 Οκτωβρίου 2018 Δημοσ. 23 Οκτωβρίου 2018 Σχετικά με τα imports αν δεν δούμε το directory structure είναι δύσκολο να απαντήσουμε. Αν και νομίζω ότι κινείσαι προς λάθος κατεύθυνση. Τα globals σπάνια είναι η ενδεδειγμένη λύση (χωρίς να σημαίνει ότι κάποιες φορές δεν είναι απαραίτητα). Anyway, αυτό το παράδειγμα πιστεύω θα σε ξεμπλοκάρει. 1
dancer_69 Δημοσ. 23 Οκτωβρίου 2018 Μέλος Δημοσ. 23 Οκτωβρίου 2018 Δεν θέλω σώνει και καλά να χρησιμοποιήσω globals, αυτό που θέλω είναι να χρησιμοποιήσω κείμενο από το ένα αρχείο/παράθυρο, στο άλλο. Απλά αυτό βρήκα που μου φάνηκε συναφές με αυτό που θέλω και προσπάθησα να το υλοποιήσω. Με λίγο περισσότερο ψάξιμο είδα πάντως ότι πιο ενδεδειγμένος τρόπος θεωρούνται τα signals, αλλά το μόνο σχετικό παράδειγμα που βρήκα ως τώρα κι εκεί δεν κατάφερα ως τώρα να το προσαρμόσω στον κώδικά μου. Το παράδειγμα από το link που παρέθεσες δεν καταλαβαίνω πως θα με βοηθήσει όμως? Απ' ότι είδα αναφέρεται σε παραδείγματα διάφορων τύπων διαλόγου. Τους διαλόγους μπορώ να τους συνδέσω και εμφανίσω από το κεντρικό παράθυρο της εφαρμογής, καθώς και να ορίσω ενέργειες στα κουμπιά ή σε άλλα περιεχόμενα στοιχεία τους(τουλάχιστον ότι έχω χρειαστεί ως τώρα). Το πρόβλημα είναι πως θα συνδέσω διαφορετικούς διαλόγους/παράθυρα μεταξύ τους ώστε να είναι δυνατή η ανταλλαγή δεδομένων. Και πάνω σ' αυτό, δεν βλέπω να έχει κάτι ο σύνδεσμος που παρέθεσες.
pmav99 Δημοσ. 23 Οκτωβρίου 2018 Δημοσ. 23 Οκτωβρίου 2018 Disclaimer: Πάνε χρόνια από την τελευταία φορά που τα κοίταξα αυτά οπότε μπορεί να μη θυμάμαι σωστά όλες τις λεπτομέρειες + μπορεί να έχουν αλλάξει κάποια πράγματα με το Qt5 Κάθε widget (πρέπει) να έχει ένα parent https://stackoverflow.com/questions/35782474/pyqt-parent-for-widgets-necessary Στην κορυφή της ιεραρχίας βρίσκεται το main window και όλα τα widgets είναι παιδιά/εγγόνια/δισέγγονα/κτλ Τον «γονιό» του κάθε widget μπορείς να τον βρεις με self.parent Tον «παππού» μπορείς να τον βρείς με self.parent.parent Τα παιδιά του κάθε widget μπορείς να τα βρεις και με μια μέθοδο (findChildren???) αν και αυτό που συνήθως κάνεις είναι να αποθηκεύσεις ένα reference του child στον parent. Πχ αν είσαι στο main window θα αποθηκεύσεις δύο comboboxes ως self.combo1 = QComboBox(self) self.combo2 = QComboBox(self) Κρατάς δηλαδή references για κάθε widget που θα χρειαστείς. Γενικά, αν χρειαστείς δηλαδή να πάρεις στοιχεία από το custom_widget του parent σου κάνεις self.parent.custom_widget.<get_method>() Αν πάλι χρειαστείς το αντίστροφο, δηλαδή μέσα από τον 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 κτλ
dancer_69 Δημοσ. 23 Οκτωβρίου 2018 Μέλος Δημοσ. 23 Οκτωβρίου 2018 Κατ' αρχήν ευχαριστώ για τον κόπο που έκανες να αναλύσεις τα παραπάνω. Παρότι είναι αρκετά διαφωτιστικά, ή δεν έχω καταλάβει ακόμη πως λειτουργούν(αρκετά πιθανό αυτό 😂), ή κάτι ακόμη χρειάζεται, λόγω του τρόπου που δημιουργούνται και συνδέονται μεταξύ τους τα 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 του κεντρικού παραθύρου? Μήπως χρειάζεται να οριστούν κάπως στον παραπάνω κώδικα, ή κάπου αλλού?
pmav99 Δημοσ. 23 Οκτωβρίου 2018 Δημοσ. 23 Οκτωβρίου 2018 (επεξεργασμένο) Είναι δική σου απόφαση βέβαια, αλλά εγώ στη θέση σου, τουλάχιστον μέχρι να αποκτούσα καλύτερη κατανόηση του τι γίνεται και γιατί, θα σταματούσα να χρησιμοποιώ το Qt Designer. Αν μη τι άλλο, το να γράψεις το UI με κώδικα είναι διδακτικό και στην πράξη δεν είναι και τόσο χρονοβόρο (αν έχεις αποφασίσει πως θες να είναι το design). IMHO εργαλεία σαν το Qt Designer έχουν νόημα μόνο αν ήδη γνωρίζεις πολύ καλά τις βιβλιοθήκες που χρησιμοποιείς + αν η δουλειά σου είναι να φτιάχνεις GUI όλη μέρα. Επεξ/σία 23 Οκτωβρίου 2018 από pmav99
dancer_69 Δημοσ. 26 Οκτωβρίου 2018 Μέλος Δημοσ. 26 Οκτωβρίου 2018 Απαντάω με καθυστέρηση, ότι το πρόβλημα έχει λυθεί, με τη χρήση του "parent". Ήταν αρκετά απλό τελικά. Έπρεπε να γίνουν τα παρακάτω, επειδή όλες οι φόρμες που δημιουργεί το qt designer έχουν parent=None: Μία αλλαγή στην __init__ def __init__(self, parent): και ορισμός στην __init__ : self.parent=parent Έπειτα είναι δυνατή η χρήση των widgets με το "self.parent.<ονομα_widget>.method" όπως ανέφερε ο @pmav99
Προτεινόμενες αναρτήσεις
Δημιουργήστε ένα λογαριασμό ή συνδεθείτε για να σχολιάσετε
Πρέπει να είστε μέλος για να αφήσετε σχόλιο
Δημιουργία λογαριασμού
Εγγραφείτε με νέο λογαριασμό στην κοινότητα μας. Είναι πανεύκολο!
Δημιουργία νέου λογαριασμούΣύνδεση
Έχετε ήδη λογαριασμό; Συνδεθείτε εδώ.
Συνδεθείτε τώρα