Python Forum
[PyQt] Send data between windows Pyqt5 and Qt Designer - Printable Version

+- Python Forum (https://python-forum.io)
+-- Forum: Python Coding (https://python-forum.io/forum-7.html)
+--- Forum: GUI (https://python-forum.io/forum-10.html)
+--- Thread: [PyQt] Send data between windows Pyqt5 and Qt Designer (/thread-20808.html)



Send data between windows Pyqt5 and Qt Designer - kkonrad002 - Aug-31-2019

I stuck with programming as I can't find solution.
I design simple windows in qt designer .ui files.
File number 1 is main window okno1.ui and window number 2 is qwidget okno2.ui
Then I created script in python which open both windows. However I don't know how to make any communication between the windows. I would like to send some data from window one to window two and from window 2 to window one. I need simple example and explanation. Ideal for me would be if you could put some code to my script which get from list widget (window one) and put to choosen_addres label to window 2. And from window two from line edit to list widget in window one.

I do not want to convert ui to py as I plan to modify the ui files in the future.


window1 -okno1.ui is:
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>MainWindow</class>
 <widget class="QMainWindow" name="MainWindow">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>800</width>
    <height>600</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>MainWindow</string>
  </property>
  <widget class="QWidget" name="centralwidget">
   <widget class="QListWidget" name="listWidget">
    <property name="geometry">
     <rect>
      <x>70</x>
      <y>80</y>
      <width>131</width>
      <height>311</height>
     </rect>
    </property>
    <item>
     <property name="text">
      <string>Adres 1</string>
     </property>
    </item>
    <item>
     <property name="text">
      <string>Adres 2</string>
     </property>
    </item>
   </widget>
   <widget class="QLabel" name="label">
    <property name="geometry">
     <rect>
      <x>70</x>
      <y>30</y>
      <width>251</width>
      <height>41</height>
     </rect>
    </property>
    <property name="text">
     <string>List of adress</string>
    </property>
   </widget>
   <widget class="QPushButton" name="pushButton">
    <property name="geometry">
     <rect>
      <x>70</x>
      <y>420</y>
      <width>85</width>
      <height>27</height>
     </rect>
    </property>
    <property name="text">
     <string>Add adress</string>
    </property>
   </widget>
  </widget>
  <widget class="QStatusBar" name="statusbar"/>
 </widget>
 <resources/>
 <connections/>
</ui>
Window2 okno2.ui is:
<?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>558</width>
    <height>446</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>Form</string>
  </property>
  <widget class="QLabel" name="label">
   <property name="geometry">
    <rect>
     <x>50</x>
     <y>40</y>
     <width>191</width>
     <height>17</height>
    </rect>
   </property>
   <property name="text">
    <string>Give name of adress</string>
   </property>
  </widget>
  <widget class="QPushButton" name="pushButton">
   <property name="geometry">
    <rect>
     <x>50</x>
     <y>280</y>
     <width>85</width>
     <height>27</height>
    </rect>
   </property>
   <property name="text">
    <string>Accept</string>
   </property>
  </widget>
  <widget class="QLineEdit" name="lineEdit">
   <property name="geometry">
    <rect>
     <x>170</x>
     <y>30</y>
     <width>151</width>
     <height>27</height>
    </rect>
   </property>
  </widget>
  <widget class="QLabel" name="chosen_adress">
   <property name="geometry">
    <rect>
     <x>190</x>
     <y>100</y>
     <width>211</width>
     <height>131</height>
    </rect>
   </property>
   <property name="text">
    <string/>
   </property>
  </widget>
 </widget>
 <resources/>
 <connections/>
</ui>
My python script is:
# Skrypt odczytuje plik Ui z designera  (script open ui files)

import sys
from PyQt5 import QtCore, QtGui, QtWidgets, uic
from PyQt5.QtCore import pyqtSlot
from PyQt5.QtWidgets import QDialog


class Window2(QDialog):
    def __init__(self):
        super().__init__()
        uic.loadUi("/home/ewcia/PycharmProjects/Designer_ui/okno2.ui",self) #link to window 2
        self.pushButton.clicked.connect(self.akcja2)


    pyqtSlot()
    def akcja2(self):
        new_adres= self.lineEdit.text()
        # How to add this new address to Mywindow


#---------------------------------------------------------------------------------------------------------

class Mywindow(QtWidgets.QMainWindow):
    def __init__(self):
        super(Mywindow,self).__init__()
        uic.loadUi("/home/ewcia/PycharmProjects/Designer_ui/okno1.ui", self) #link to open okno 1 on my disk

        self.pushButton.clicked.connect(self.akcja1)
    pyqtSlot()
    def akcja1(self):
        #print("druga akcja Drugie Okno")
        self.okno2 = Window2()
        self.okno2.show()



if __name__== "__main__":
    import sys
    app=QtWidgets.QApplication(sys.argv)
    window=Mywindow()
    window.show()
    sys.exit(app.exec_())
I would be glad for any help


RE: Send data between windows Pyqt5 and Qt Designer - Alfalfa - Aug-31-2019

Use PyQt signal and slot mechanism. Something like this:

import sys
from PyQt5 import QtCore, QtGui, QtWidgets, uic
from PyQt5.QtWidgets import QDialog


class Window2(QDialog):
    signal = QtCore.pyqtSignal(str)

    def __init__(self):
        super().__init__()
        uic.loadUi("/home/ewcia/PycharmProjects/Designer_ui/okno2.ui",self) #link to window 2
        self.pushButton.clicked.connect(self.akcja2)


    pyqtSlot()
    def akcja2(self):
        new_adres= self.lineEdit.text()
        self.signal.emit(new_adres)
        # How to add this new address to Mywindow


#---------------------------------------------------------------------------------------------------------

class Mywindow(QtWidgets.QMainWindow):
    def __init__(self):
        super(Mywindow,self).__init__()
        uic.loadUi("/home/ewcia/PycharmProjects/Designer_ui/okno1.ui", self) #link to open okno 1 on my disk

        self.pushButton.clicked.connect(self.akcja1)

    def akcja1(self):
        #print("druga akcja Drugie Okno")
        self.okno2 = Window2()
        self.okno2.signal.connect(self.slot)
        self.okno2.show()

    QtCore.pyqtSlot(str)
    def slot(self, addr):
      print(addr)



if __name__== "__main__":
    import sys
    app=QtWidgets.QApplication(sys.argv)
    window=Mywindow()
    window.show()
    sys.exit(app.exec_())



RE: Send data between windows Pyqt5 and Qt Designer - Denni - Sep-03-2019

Two things if you are going to be working with Threads and/or Signal/Slots I can help with that as I have been wrestling with that aspect of pyqt for a while and recently discovered that the current documentation on Threading is wrong in its implementation.

The second thing is I would strongly suggest you stop using the Designer it really is not what you want to do as the mess of code it provides is extremely difficult to work with and actually coding a window manually is not that big of deal once you have seen how its down and the manual code version is extremely easy to work with later on.

Again if you need extended help I more than willing to lend some guidance. If you have access to Discord I even have a message server where I am periodically helping several other newbie programmers with python/pyqt5 if interested just let me know.


RE: Send data between windows Pyqt5 and Qt Designer - Axel_Erfurt - Sep-03-2019

(Aug-31-2019, 05:27 PM)Alfalfa Wrote: Use PyQt signal and slot mechanism. Something like this:

you forgot 'QtCore.'

should be

    QtCore.pyqtSlot()
    def akcja2(self):
        new_adres= self.lineEdit.text()
        self.signal.emit(new_adres)



RE: Send data between windows Pyqt5 and Qt Designer - Denni - Sep-04-2019

@Alfalfa you do realize that there are quite a few issues with that code you submitted and NOTE I am not certain if this is due to copy/paste issues or not but you ought not to present bad code as a solution even if you copy/pasted it that way:

For instance you import sys twice which is definitely not necessary and you add in sys.argv but never use it and the only thing you really need from sys is the exit function so why import that entire library? This also goes for QtCore, QtGui (which you never use) and QtWidgets your imports should have looked like this:

from PyQt5.QtCore import pyqtSignal, pyqtSlot
# from PyQt5.QtGui import ?? just a place holder for future purposes
from PyQt5.QtWidgets import QApplication, QMainWindow, QDialog
You reference self.pushButton outside its definition area which can be extremely confusing? This is another reason not to use that horrible UI file concept -- every static reference like that ought to be grouped together - the only thing appearing else where would be stuff that needs to be changed dynamically and I would argue strongly that the pushbutton.clicked event is not actually dynamic in this case as it does not change once set and could be set on creation if it had been done properly

Lastly one does not need to use the complexity of Signal/Slots since they are not in separate Threads (and never could be) nor are they in separate processes (since multiprocess was not used) one just has to pass a handle to the QMainWindow to the QDialog as follows:

# Where it is created in QMainWindow
self.okno2 = Window2(self)
# . . .
# Where it is declared
class Window2(QDialog):
    def __init__(self, parent):
        super().__init__()
        self.Parent = parent
As the parent (QMainWindow) can always reference the child window and now the child window (QDialog) has a means to reference its parent - easy peasy


RE: Send data between windows Pyqt5 and Qt Designer - Alfalfa - Sep-04-2019

It is OP code, obviously, I just added a signal and slot exemple on top of it... To maintain a proper code structure, in most cases I believe it is best to handle all the windows and threads from the main thread, signals are great for that. In the long run it also makes it easier to split the code into modules and to maintain it IMO.


RE: Send data between windows Pyqt5 and Qt Designer - Denni - Sep-04-2019

Okay Signal/Slots IMO should only be used with Threads as they are about 10x slower than a direct call as well as adding in a level of complexity that is completely unnecessary especially when -- Every Parent has direct access to all its Children within the same thread AND passing a parent-handle to a Child is extremely simple and works even if you modularize your code. Bascially the parent is the parent regardless of how you split your code into modules so there would (or should) be no issue there at all.


RE: Send data between windows Pyqt5 and Qt Designer - Alfalfa - Sep-05-2019

(Sep-04-2019, 09:36 PM)Denni Wrote: Okay Signal/Slots IMO should only be used with Threads as they are about 10x slower than a direct call as well as adding in a level of complexity that is completely unnecessary especially when -- Every Parent has direct access to all its Children within the same thread AND passing a parent-handle to a Child is extremely simple and works even if you modularize your code. Bascially the parent is the parent regardless of how you split your code into modules so there would (or should) be no issue there at all.

Of course if you only have one parent and one child which both live in the same thread, you can use a direct call. What I meant is creating children in the main thread, then linking them together by using signals and slots. This way the order in which the instances are created has no importance and the code is more robust (read less fragile). It also allow to send call to many children at once, by emitting a single signal, and is always thread safe. It is much easier to maintain than linking the modules with spaghetti calls all over the place. IMHO Wink


RE: Send data between windows Pyqt5 and Qt Designer - Denni - Sep-05-2019

@Alfalfa okay I have never in my years experienced a situation in a single application where what you describe would exist and if it did exist I would say it was a poor design to begin with. You should never have a need in a single thread application to broadcast a command since everything is for the most part linear -- as in you can only process one path at a time -- creating something like you describe would mostly likely end up being a debugging nightmare (I have had to work on stuff where someone did something that hopped all over the place based on events and it had a bug -- it took a while to track it down and then they asked me to re-code it so that it was not such a nightmare later on -- and frankly the re-write was I think 3x to 5x faster and definitely easier to follow and maintain)

Further yes I am to against spaghetti calls and/or spaghetti code for that matter. I believe in the K.I.S.S. principle (Keep It Simple and Smart) which means do not use something more complex than what your code calls for. Yes sometimes complex methodologies are needed but using one when it is not needed is just not Smart and can lead to unnecessary issues later on.