0

I have this:

oknoGlowne.py - main module :

    from oknoNazwa import oknoNazwa
    from oknoKola import oknoKola
    from oknoIkona import oknoIkona
    import sys
    from PyQt5.QtWidgets import *
    from PyQt5.QtGui import *
    from PyQt5.QtCore import *

    class Main(QMainWindow):

        def __init__(self):
            QMainWindow.__init__(self)
            self.initUI()

        def initMenu(self):
            menu = self.menuBar()

            dialog = menu.addMenu("Dialog")

            nazwa = QAction("Nazwa okna głównego", self)
            nazwa.setCheckable(1)
            self.oknoNazwa = oknoNazwa()
            nazwa.triggered.connect(lambda: self.oknoNazwa.show())
            kola = QAction("Ustaw koła", self)
            kola.setCheckable(1)
            self.oknoKola = oknoKola()
            kola.triggered.connect(lambda: self.oknoKola.show())
            ikona = QAction("Zmień ikonę", self)
            ikona.setCheckable(1)
            self.oknoIkona = oknoIkona()
            ikona.triggered.connect(lambda: self.oknoIkona.show())

            dialog.addAction(nazwa)
            dialog.addAction(kola)
            dialog.addAction(ikona)

        def initUI(self):
            self.setGeometry(100, 100, 300, 200)
            self.setMinimumSize(300,200)
            self.setWindowTitle("Notatnik")
            self.initMenu()

        def zmianaNazwy(self, tekst):
            self.setWindowTitle(tekst)


    def main():

        app = QApplication(sys.argv)

        okno = Main()
        okno.show()

        sys.exit(app.exec_())

    if __name__ == "__main__":
        main()

And oknoNazwa.py - secondary module:

import sys
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *

class oknoNazwa(QDialog):

    def __init__(self):
        QDialog.__init__(self)
        self.initUI()


    def initUI(self):
        self.setModal(0)
        self.resize(200,60)
        self.setWindowTitle("Zmień nazwę")
        vbox = QVBoxLayout()
        label = QLabel("Podaj nową nazwę programu:")
        vbox.addWidget(label)
        pole=QLineEdit()
        vbox.addWidget(pole)
        buttony = QWidget()
        vbox.addWidget(buttony)
        hbox = QHBoxLayout()
        okButton = QPushButton("Zatwierdź")
        cancelButton = QPushButton("Anuluj")
        hbox.addWidget(okButton)
        hbox.addWidget(cancelButton)
        buttony.setLayout(hbox)

        okButton.clicked.connect(lambda: self.zmienNazwe)
        cancelButton.clicked.connect(lambda: self.done(1))
        self.setLayout(vbox)

    def zmienNazwe(self):
        self.Main.zmianaNazwy(self.pole.text())
        self.done(1)

How do I call function which belongs to main module - zmianaNazwy() in secondary module which is dialog with textfield containing string value of new main window title. I also want to wrap that function in another function so I can attach it's action to button, but maybe that's unnessesary and a calling a main modules name changing function would be enough. So the question is how do I do that?

As you can see I've tried to do it with like self.main class but that doesn't work, also even the self.done(1) isn't executed, I guess it's because self is taken as QPushButton but I might be wrong so clarify me.

2LDR -> How to call a function from main module in dialog (and assign it to a button action in that dialog) which is in another module which is being called on button press in main module?

Koniotaur
  • 11
  • 1
  • 6
  • You must import the first package into the second package. – Ali.Turkkan Dec 13 '18 at 14:14
  • @Ali.Turkkan and then how do I call main class method from within oknoNazwa class? – Koniotaur Dec 13 '18 at 14:15
  • That may help similar question. [Here](https://stackoverflow.com/questions/53022217/pyqt5-getting-values-from-qdialog-window-to-mainwindow-after-close) – Pavel.D Dec 13 '18 at 14:20
  • @Koniotaur f you are still thinking that the program is a set of files or modules then you are going the wrong way. When each class is designed, it should have a single responsibility and should not depend on doing that task. You have to call the function where the objects of both classes have the same scope, if it does not exist then create another file where you create those objects, and if you still can not then redesign your class. – eyllanesc Dec 13 '18 at 14:51

2 Answers2

1

deneme2.py

class package1:
    def main(self):
        print('a')

deneme1.py

from deneme2 import package1

package1().main()

Output:

a
Ali.Turkkan
  • 266
  • 2
  • 11
0

First, don't think in terms of "modules" and "functions" when what you want is for an object to access methods of another objects. What your oknoNazwa.oknoNazwa object needs is not to "call the function zmianaNazwy() of the main module", but to call the .zmianaNazwy() method of the main.Main instance that created the oknoNazwa.oknoNazwa instance.

The solution here is, obviously, to change oknoNazwa.oknoNazwa so that it takes a reference either to the main.Main instance itself or to the current main.Main instance's .zmianaNazwy method (since python methods are objects too), then to make main.Main pass itself (or it's .zmianaNazwy method) to oknoNazwa.oknoNazwa. Toy example:

# sub.py
class Sub(object):
    def __init__(self, main):
        self.main = main

    def do_this(self):
        print(self.main.do_that(42))

and

# main.py
from sub import Sub

class Main(object):
    def __init__(self, name):
        self.name = name
        self.sub = Sub(self)

    def do_that(self, bar):
        return "hello, I'm {} and the answer is {}".format(self.name, bar)


    def run(self):
       self.sub.do_this()


m = Main("Arthur")
m.run()

As a side note: naming conventions are to use all_lower_with_underscore for module names and CamelCase for classes, so it should be "oknonazwa" (module) and "OknoNazwa" (class). Also, Python doesn't mandate (nor recommand) the javaish "one file per class" approach - you can have has many classes, functions etc as you want in a same module. And finally, start imports (ie rom PyQt5.QtWidgets import *) should be avoided if you value your mental sanity - even if the lib's doc states that's "it's ok" and uses it in all it's example, that's still a terrible thing to do wrt/ maintainability.

Fred Gandt
  • 4,217
  • 2
  • 33
  • 41
bruno desthuilliers
  • 75,974
  • 6
  • 88
  • 118
  • I tried to do it like this: `okButton.clicked.connect(lambda: self.zmienNazwe)` `def zmienNazwe(self): self.Main.zmianaNazwy(self.pole.text())` But it simply doesn't work :/ – Koniotaur Dec 13 '18 at 14:52
  • A couple lines of code in a comment, out of the context, are totally useless - please provide a proper MCVE (https://stackoverflow.com/help/mcve). And "does not work" is also totally useless as a problem description, you have to describe the exact result you get (and if it's an error, provide the _full_ traceback). – bruno desthuilliers Dec 13 '18 at 14:55
  • It gives no error's, nothing happens once I click okButton which should pass name to main window and change it.And about imports, I have to do that only for college I'm not really into python, it has terrible syntax and the code is mess for me. – Koniotaur Dec 13 '18 at 14:57
  • @Koniotaur please re-read my dumbed-down example and see how it differs from your (obviously incomplete BTW) code snippet: I'm passing the `main.Main` __instance__ to `Sub()` (`self.sub = Sub(self)`, so `sub` can call back on the `main.Main` instance. – bruno desthuilliers Dec 13 '18 at 15:00
  • The problem has nothing to do with Python (which is considered one of the most readable language ever FWIW), the issue (and the solution) would be the same whatever the language. The problem is that you don't seem to get the difference between a class and an instance of a class. – bruno desthuilliers Dec 13 '18 at 15:02
  • The problem is I've been said, here do this in python without any claryfing or studying python before. It's a shame but that's how it is. – Koniotaur Dec 13 '18 at 15:07
  • Once again it's not a Python issue in itself, you'll get the same issue in any OOPL: if you want an object B to call a method of another object A, B must have a reference (pointer, whatever the language-specific terminology) on A, and in this case (where A creates B) the simple obvious solution is that A passes itself to B. – bruno desthuilliers Dec 13 '18 at 15:26