I have two python programs opened at the same time, and i would like that when i click one button in the first app, "send" some information to the second app.
Im trying to do by signals from PySide. I get how to send it with this little code:
from PySide.QtGui import *
from PySide.QtCore import *
from PySide import QtGui, QtCore, QtUiTools
class Foo(object):
pass
class MyWidget(QWidget):
mysignal = QtCore.Signal(int, str)
def __init__(self, parent=None):
super(MyWidget, self).__init__(parent)
self.hlayout = QHBoxLayout()
self.setLayout(self.hlayout)
self.b = QPushButton("Emit your signal!", self)
self.hlayout.addWidget(self.b)
self.b.clicked.connect(self.clickHandler)
self.mysignal.connect(self.mySignalHandler)
def clickHandler(self):
self.mysignal.emit(123, "")
def mySignalHandler(self, n):
print n
# print l
if __name__ == '__main__':
import sys
app = QApplication(sys.argv)
w = MyWidget()
w.show()
sys.exit(app.exec_())
but i dont know how can i "recieve" this signal in the other python app.
Thanks for your help!
You need to think about the apps communication ways, it's multi-thread or multi-process?
Related
I am making a web browser using PyQt5. I am using the following code:
import PyQt5
from PyQt5.QtCore import QUrl
from PyQt5.QtWidgets import QApplication, QWidget
from PyQt5.QtWebKitWidgets import QWebView , QWebPage
from PyQt5.QtWebKit import QWebSettings
from PyQt5.QtNetwork import *
import sys
from optparse import OptionParser
class Browser(QWebView):
def __init__(self):
# QWebView
self.view = QWebView.__init__(self)
#self.view.setPage(MyBrowser())
self.setWindowTitle('Loading...')
self.titleChanged.connect(self.adjustTitle)
#super(Browser).connect(self.ui.webView,QtCore.SIGNAL("titleChanged (const QString&)"), self.adjustTitle)
def load(self,url):
self.setUrl(QUrl(url))
def adjustTitle(self):
self.setWindowTitle(self.title())
app = QApplication(sys.argv)
view = Browser()
view.showMaximized()
view.load("https://duckduckgo.com")
app.exec_()
However, this is what I get:
Can someone please tell me where I am going wrong? Note that it is not a problem of the website. I have tried it with Wikipedia, Stack Overflow and Google. I am using PyQt5 version 5.10.1.
In case you want fullscreen, you have to use:
class Browser(QWebView):
def __init__(self):
# QWebView
self.view = QWebView.__init__(self)
#self.view.setPage(MyBrowser())
self.setWindowTitle('Loading...')
self.titleChanged.connect(self.adjustTitle)
self.showFullScreen()
class Browser(QWebView):
def __init__(self):
super().__init__()
def load(self, url):
self.setUrl(QUrl(url))
def adjustTitle(self):
self.setWindowTitle(self.title())
if __name__ == '__main__':
app = QApplication(sys.argv)
window = Browser()
window.setWindowTitle('Loading...')
window.titleChanged.connect(window.adjustTitle)
window.load("https://duckduckgo.com")
window.showMaximized()
sys.exit(app.exec_())
The program does not know the real sizes of your device so it creates a maximum on its assumed geometry.
You should provide the actual geometry by resize then call showMaximized. So that your geometry will be reachable by the program and a true maximized window will be displayed.
self.resize(998, 878)
self.showMaximized()
import sys
from PySide2.QtCore import QFile
from PySide2.QtWidgets import QApplication, QMainWindow
from PySide2.QtUiTools import QUiLoader
class MyMainWindow(QMainWindow):
def __init__(self):
super().__init__()
loader = QUiLoader()
self.ui = loader.load("mainWindow.ui", self)
self.ui.pushButton_call_dialog.clicked.connect(self.call_dialog)
self.ui.close()
self.ui.show()
def call_dialog(self):
loader = QUiLoader()
self.dialog = loader.load("dialog.ui")
self.dialog.show()
if __name__ == '__main__':
app = QApplication(sys.argv)
window = MyMainWindow()
window.show
sys.exit(app.exec_())
Hi everyone,
any idea why the second (dialog) window closes the entire application?
Of course, it is not a crash since i'm getting a message saying:
Process finished with exit code 0
Thanks for your help
You could handle your QDialog on a separate class, and then make them interact only, the structure might change a bit, but you can see if it's a viable answer:
import sys
from PySide2.QtWidgets import *
class MyWindow(QMainWindow):
def __init__(self):
QMainWindow.__init__(self)
button = QPushButton("Dialog")
button.clicked.connect(self.open_dialog)
self.setCentralWidget(button)
def open_dialog(self):
dialog = MyDialog()
dialog.show()
dialog.exec_()
class MyDialog(QDialog):
def __init__(self):
QDialog.__init__(self)
button = QPushButton("Close")
button.clicked.connect(self.close_dialog)
layout = QHBoxLayout()
layout.addWidget(button)
self.setLayout(layout)
def close_dialog(self):
self.close()
if __name__ == "__main__":
app = QApplication()
m = MyWindow()
m.show()
sys.exit(app.exec_())
Just notice that you should include the setUp step on each class.
Hope it helps.
To put the dialog into a separate class didn't work for either.
Every time the Dialog.close() event was called, it closes the whole application.
What worked for me, was to use hide() instead
I have got two main-windows which will run all the time and open other windows. Every window has to communicate with each other. All windows are created with qt designer and as I read in another question I should not modify these files, so I tried to make a new class (communicator) to handle all the jobs.
What is the best way to structure a project like this. So how can i communicate best between these windows now, e.g. if I press a button in 'self.mainWindows_images' I want to do something in 'self.mainWindows_classifier'
from classifier import Form as Form_classifier
from cnn_avg import Form as Form_cnn_avg
from images import Form as Form_images
from PyQt4.QtGui import *
from PyQt4.QtCore import *
import sys
class Communicator():
def __init__(self, parent=None):
self.mainWindow_images = Form_images()
self.mainWindow_images.show()
self.mainWindow_classifier = Form_classifier()
self.mainWindow_classifier.show()
def main():
app = QApplication(sys.argv)
app.setStyle('cleanlooks')
comm = Communicator()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
One of the window files, generated by Qt Designer, looks like with the additional -w flag:
class Ui_Form(object):
def setupUi(self, Form):
Form.setObjectName(_fromUtf8("Form"))
Form.resize(1145, 654)
...
class Form(QtGui.QWidget, Ui_Form):
def __init__(self, parent=None, f=QtCore.Qt.WindowFlags()):
QtGui.QWidget.__init__(self, parent, f)
self.setupUi(self)
I want to do something like this and add the setImage-method to the mainWindow_classifier, becaus as I mentioned I should not modify the generated qt python file:
self.mainWindow_classifier.pushButton.clicked.connect(self.setImage)
def setImage(self):
# change QLabel in self.mainWindow_images
I try to get the value of Count_total_value in my user interface when I call Continusread method, (it should be "toto" according to what I want to do) but it is always the default value "azerty" which is displayed. Please can you tell me where I am wrong?
This is my code:
#!/usr/bin/env python3
from PyQt4 import QtCore, QtGui
import sys
import os
import subprocess
import time
import threading
from ctypes import *
import ctypes
#import Converted Python UI File
from test_error_rx import Ui_MainWindow
class MyThread(QtCore.QThread):
Count_total_valuechanged = QtCore.pyqtSignal(str)
def __init__(self, parent=None):
super(MyThread, self).__init__(parent=parent)
self.Count_total_value = 'Azerty'
def run(self):
##do things to calculate Count_total_value
Count_total_value='toto'
self.Count_total_valuechanged.emit((self.Count_total_value))
time.sleep(0.1)
class Main( QtGui.QMainWindow,QtGui.QWidget):
def __init__(self):
QtGui.QMainWindow.__init__(self)
self.ui = Ui_MainWindow()
self.ui.setupUi(self)
# Connect the Buttons
QtCore.QObject.connect(self.ui.Continusread,QtCore.SIGNAL("clicked()"),self.Continusread)
self.__thread = MyThread(self)
self.__thread.Count_total_valuechanged.connect(self.ui.Count_total.setText)
def Continusread(self):
self.__thread.start()
def main():
app = QtGui.QApplication(sys.argv)
window = Main()
window.show()
sys.exit(app.exec_())
if __name__ == "__main__":
main()
In the run() method of your thread class MyThread you set Count_total_value='toto' when it should be self.Count_total_value='toto'.
Note that when posting on stackoverflow you should:
post a minimilistic working example (you haven't included your UI in the above code so no-one can run your script)
Check the posted code has the correct indentation and fix any mistakes (your posted code is a mess of incorrect indentation)
I am coding a application which needs a custom buttons in QMessageBox. i managed to create an example in QT designer which is given below.
i wanted to do this in a QMessageBox.
I am using python 2.6.4 and PyQt4. please, can any one help.
Here is an example of building a custom message box from the ground up.
import sys
from PyQt4 import QtCore, QtGui
class Example(QtGui.QDialog):
def __init__(self, parent=None):
super(Example, self).__init__(parent)
msgBox = QtGui.QMessageBox()
msgBox.setText('What to do?')
msgBox.addButton(QtGui.QPushButton('Accept'), QtGui.QMessageBox.YesRole)
msgBox.addButton(QtGui.QPushButton('Reject'), QtGui.QMessageBox.NoRole)
msgBox.addButton(QtGui.QPushButton('Cancel'), QtGui.QMessageBox.RejectRole)
ret = msgBox.exec_()
if __name__ == "__main__":
app = QtGui.QApplication(sys.argv)
ex = Example()
ex.show()
sys.exit(app.exec_())
manuel-gutierrez, why do you inherit from QDilaog? You can inherit from QMessageBox. It's much simpler and less code
import sys
from PyQt4.QtGui import QMessageBox, QPushButton, QApplication
from PyQt4.QtCore import Qt
class ErrorWindow(QMessageBox):
def __init__(self, parent=None):
QMessageBox.__init__(self, parent)
self.setWindowTitle("Example")
self.addButton(QPushButton("Yes"), QMessageBox.YesRole )
self.addButton(QPushButton("No"), QMessageBox.NoRole)
self.addButton(QPushButton("Cancel"), QMessageBox.RejectRole)
if __name__ == "__main__":
app = QApplication(sys.argv)
ex = ErrorWindow()
ex.setText("some error")
ex.show()
sys.exit(app.exec_())
The standard QMessageBox "impose an interpretation of the response", being accepted, rejected or canceled.
Here is a version that allows arbitrary buttons, as much as wanted, and leave the interpreatation up to the user.
And it simplifies the sourcecode a bit.
The argument "buttons" gives a text list, this makes the buttons.
The return value is the text of the clicked botton.
So the user can do what he want's with that.
Note: This might be against UI-Standards and therefore less robust, but hey.
Note2: Since it's 2021, i use PyQt5 and python 3.7
I just posted this in case someone prefer this more generic approach.
#!/usr/bin/python3
# -*- coding: utf-8 -*-
""" A more generic, a bit simplified message box also known as 'popup' """
from PyQt5 import QtWidgets as QW
class Popup(QW.QMessageBox):
def __init__(
self,
title,
text,
buttons = ["Ok"]
):
super(Popup, self).__init__()
self.setWindowTitle(title)
self.setText(text)
self.buttons = buttons
for txt in self.buttons:
b = QW.QPushButton(txt)
self.addButton(b, QW.QMessageBox.NoRole)
def do(self):
answer = self.exec_()
text = self.buttons[answer]
return text
if __name__ == "__main__": # test
class Tester(QW.QWidget):
def __init__(self):
super(Tester, self).__init__()
btn = QW.QPushButton("do it")
btn.clicked.connect(self.klick)
layout = QW.QHBoxLayout(self)
layout.addWidget(btn)
def klick(self, text):
r = Popup(
"choose a letter",
"What is your favorite\nLetter\namong a to e ?",
buttons = "a,b,c,d,e".split(","))
print("result = ",r.do())
import sys
app = QW.QApplication(sys.argv)
widget = Tester()
widget.setGeometry(400,400,100,100)
widget.show()
sys.exit(app.exec_())