how to set a function output as a signal in pyqt5 - python-3.x

I want to display the logged in user os.getlogin() displayed in a label widget.
So far I need to set a custom signal and connect it to the label
here is my (not functioning) code, hope you can guide my how to write it properly
import sys
import os
from PyQt5 import QtWidgets as qtw
from PyQt5 import QtCore as qtc
from PyQt5 import QtGui as qtg
class UserTest(qtw.QWidget):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
# your code will go here
user_in_label = qtw.QLabel()
layout = qtw.QVBoxLayout()
layout.addWidget(user_in_label)
# funktionen
self.trigger = qtc.pyqtSignal(str)
# fire signal to slot
self.set_signal.connect(user_in_label.setText)
# your code ends here
self.show()
def set_signal(self):
active_user = os.getlogin()
self.trigger.emit(active_user)
if __name__ == '__main__':
app = qtw.QApplication(sys.argv)
w = UserTest()
sys.exit(app.exec_())
self.set_signal.connect(user_in_label.setText)
this line is missing an object, do I need to set a new class for this take, seems like nonsense

Try it:
import sys
import os
from PyQt5 import QtWidgets as qtw
from PyQt5 import QtCore as qtc
from PyQt5 import QtGui as qtg
class UserTest(qtw.QWidget):
trigger = qtc.pyqtSignal(str) # +++
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
user_in_label = qtw.QLabel()
layout = qtw.QVBoxLayout(self) # + self
layout.addWidget(user_in_label)
layout.addWidget(qtw.QPushButton('Click me', clicked=self.set_signal)) # +++
self.trigger.connect(user_in_label.setText) # +++
def set_signal(self):
active_user = os.getlogin()
self.trigger.emit(active_user)
if __name__ == '__main__':
app = qtw.QApplication(sys.argv)
w = UserTest()
w.show()
sys.exit(app.exec_())
Update
can you explain why you relocate trigger = qtc.pyqtSignal(str) above init ? and any suggestions how to set active user automatically to the label without the push button?
trigger must be a class attribute
import sys
import os
from PyQt5 import QtWidgets as qtw
from PyQt5 import QtCore as qtc
from PyQt5 import QtGui as qtg
class UserTest(qtw.QWidget):
trigger = qtc.pyqtSignal(str)
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
user_in_label = qtw.QLabel()
layout = qtw.QVBoxLayout(self)
layout.addWidget(user_in_label)
# layout.addWidget(qtw.QPushButton('Click me', clicked=self.set_signal))
self.trigger.connect(user_in_label.setText)
self.set_signal() # +++
def set_signal(self):
active_user = os.getlogin()
self.trigger.emit(active_user)
if __name__ == '__main__':
app = qtw.QApplication(sys.argv)
w = UserTest()
w.show()
sys.exit(app.exec_())

Related

QObject: Cannot create children for a parent that is in a different thread. (Multithreading pyqt5)

I am trying to edit the text in 'QTextEdit' but I got the error which is in the title above. I know that I shouldn't edit the widgets in the main app from another thread and I searched for some answers, But I didn't get the full answer that I want
This is a sample that produce the same error that I have
from PyQt5 import QtWidgets
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *
from PyQt5 import QtCore
import sys
import time
import threading
class Main(QMainWindow):
def __init__(self):
super().__init__()
self.move(50, 220)
self.resize(500, 500)
self.text_edit = QTextEdit(self)
self.text_edit.resize(200, 200)
self.btn = QPushButton('start', self)
self.btn.move(10, 250)
self.btn.clicked.connect(lambda x : self.thread_creator(self.test))
self.btn2 = QPushButton('print', self)
self.btn2.move(10, 290)
self.btn2.clicked.connect(lambda x : print('dad'))
def test(self):
for i in range(99):
self.text_edit.setText(f'dad {i}')
time.sleep(0.1)
def thread_creator(self, function):
self.thread = threading.Thread(target=function)
self.thread.start()
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = Main()
ex.show()
sys.exit(app.exec_())

pyqt5 button click not working from my second window

i am stuck in call function from pushButton.
in my project:
app.py, which is the main file to run the project.
ui_mainWindow.py is the file consist of tab widget.
Account.py is the converted file from account.ui
main_Account.py is the file where i import Account.py file.
account_handler.py is the file where consist of functions.
now when i run my project by running app.py ,it will show all contents of ui_mainWindow.py .now if i choose account tab from tabwidget than it will show all contents of mainAccount.py. now if i hit a button from mainAccount.py than function will be call from account_handler.py.
everything working fine but while i hut pushButton nothin happen.
this is my previous post : PyQt5 push button method called from separate python file ,
i follow this separately and this working fine, but in my project samecode not working. can anyone tell me where i am wrong!
app.py
from importlib import reload
import PyQt5.QtCore as QtCore
from PyQt5.uic import loadUi
from PyQt5.QtWidgets import QMainWindow,QApplication
import sys
import files.interfaces.ui_mainWindow
import files.interfaces.dashboard
reload(files.interfaces.dashboard)
import files.main_Interfaces.mainAccount
reload(files.main_Interfaces.mainAccount)
import files.interfaces.account2
reload(files.interfaces.account2)
class MainWindow(QMainWindow, files.interfaces.ui_mainWindow.Ui_MainWindow):
def __init__(self):
# Base class
QMainWindow.__init__(self)
self.ui = files.interfaces.ui_mainWindow.Ui_MainWindow()
self.ui.setupUi(self)
self.setWindowTitle("PORTFOLIO ACCOUNTING")
# import tab1
self.TabWidget = QtWidgets.QWidget()
ui = files.interfaces.dashboard2.Ui_Form()
ui.setupUi(self.TabWidget)
self.ui.tabWidget.insertTab(0, self.TabWidget, "Dashboard")
# import tab2
self.TabWidget = QtWidgets.QWidget()
ui = files.main_Interfaces.mainAccount.MainWindow()
ui.setupUi(self.TabWidget)
self.ui.tabWidget.insertTab(1, self.TabWidget, "Account")
def main():
app = QtWidgets.QApplication(sys.argv)
app.setApplicationName("Portfolio Accounting")
application = MainWindow()
application.show()
app.exec_()
if __name__ == '__main__':
main()
main_Account.py
from PyQt5 import QtCore, QtGui, QtWidgets
from files.interfaces.account import Ui_Form
from event_handler.account_EventHndler import function2
class MainWindow(QtWidgets.QMainWindow,Ui_Form):
def __init__(self, parent=None):
super(MainWindow, self).__init__(parent)
self.setupUi(self)
self.pushButton_2.clicked.connect(function1)
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
w = MainWindow()
w.show()
sys.exit(app.exec_())
account_handler.py
def function1():
print("function called")
You code is a bit confusing since you use the same class names in different modules and there is an inconsistencies between the names of the modules you are importing and the names of the .py files you provided but I'm assuming that files.main_Interfaces.mainAccount.MainWindow refers to mainWindow in main_Account.py. In that case, in app.MainWindow.__init__ tab2 should probably be something like
# import tab2
self.TabWidget = files.main_Interfaces.mainAccount.MainWindow()
self.ui.tabWidget.insertTab(1, self.TabWidget, "Account")

Python: Access class method variable from another file

I have a PyQt5 GUI code and it has a Ui_MainWindow class and this class has a setupUI method. Here is my gui.py:
import io
import sys
import os
import core as c
from PyQt5 import QtCore, QtGui, QtWidgets, QtWebEngineWidgets
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(1022, 637)
MainWindow.setMinimumSize(QtCore.QSize(1022, 637))
MainWindow.setMaximumSize(QtCore.QSize(1022, 637))
font = QtGui.QFont()
font.setKerning(False)
MainWindow.setFont(font)
MainWindow.setMouseTracking(True)
MainWindow.setFocusPolicy(QtCore.Qt.NoFocus)
.
.
.
self.lineEditSiteX = QtWidgets.QLineEdit(self.centralwidget)
self.actionCalculate.triggered.connect(c.cal) # Here is where I'm stuck!!!!!!!!!!!!!!!!!!!!
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication.instance()
if app is None:
app = QtWidgets.QApplication(sys.argv)
MainWindow = QtWidgets.QMainWindow()
ui = Ui_MainWindow()
ui.setupUi(MainWindow)
MainWindow.show()
sys.exit(app.exec_())
In the comment above I'm trying to call a function from another file named core.py as as follows:
import gui
def cal():
val = gui.Ui_MainWindow().lineEditSiteX.value()
return val ** (1/val*2)
I simply want when someone clicks on Calculte the lineEdit value will be accessed through the core.py file. But it gives me an attributeError. How can I do it?
You have 2 errors:
Business logic should not depend on the GUI but the GUI should only use business logic.
PyQt recommends creating a class that inherits from the appropriate widget and using the class generated by Qt Designer (for more information read here).
Considering the above, the solution is:
core.py
def cal(val):
return val ** (1/val*2)
gui.py
import io
import sys
import os
import core as c
from PyQt5 import QtCore, QtGui, QtWidgets, QtWebEngineWidgets
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
# ...
self.lineEditSiteX = QtWidgets.QLineEdit(self.centralwidget)
class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
def __init__(self, parent=None):
super().__init__(self, parent)
self.setupUi(self)
self.actionCalculate.triggered.connect(self.on_actionCalculate)
#QtCore.pyqtSlot()
def on_actionCalculate(self):
try:
val = float(self.lineEditSiteX.text())
except ValueError:
print("error")
finally:
res = c.cal(val)
print(res)
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication.instance()
if app is None:
app = QtWidgets.QApplication(sys.argv)
w = MainWindow()
w.show()
sys.exit(app.exec_())

How to reserve space for hidden QtWaitingSpinner in QGridLayout?

I'm trying to build a QtGui application that uses the QtWaitingSpinner found here: https://github.com/z3ntu/QtWaitingSpinner. I have it in a QGridLayout. However, this means that the button next to it changes size when the spinner is unhidden and started. How do I reserve the correct amount of space for the spinner in the grid so that the button next to it stays a constant size regardless of whether the spinner is shown?
Based on this stackoverflow post How to use spacers in Qt, I suspect that the answer involves QSpacerItem. However, I can't figure out how to size the QSpacerItem based on the size the spinner will need.
Here's a minimal example of the code to show my problem:
import PyQt5.QtWidgets as QWidgets
import PyQt5.QtCore as QtCore
import PyQt5.QtGui as QtGui
from waitingspinnerwidget import QtWaitingSpinner
import sys
class Example_Window(QWidgets.QWidget):
def __init__(self):
super(QWidgets.QWidget,self).__init__()
self.initUI()
def initUI(self):
self.button=QWidgets.QPushButton("Start/Stop Spinner")
self.button.clicked.connect(self.toggle_spinner)
self.spinner = QtWaitingSpinner(self,centerOnParent=False)
self.grid = QWidgets.QGridLayout()
self.grid.addWidget(self.button,0,0)
self.grid.addWidget(self.spinner,0,1)
self.setLayout(self.grid)
self.show()
def toggle_spinner(self):
if self.spinner.isSpinning():
self.spinner.stop()
else:
self.spinner.start()
if __name__ == '__main__':
app = QWidgets.QApplication([])
main = Example_Window()
sys.exit(app.exec())
Try it:
import PyQt5.QtWidgets as QWidgets
import PyQt5.QtCore as QtCore
import PyQt5.QtGui as QtGui
from waitingspinnerwidget import QtWaitingSpinner
import sys
class Example_Window(QWidgets.QWidget):
def __init__(self):
super(QWidgets.QWidget,self).__init__()
self.initUI()
def initUI(self):
self.button = QWidgets.QPushButton("Start Spinner") # +
self.button.clicked.connect(self.toggle_spinner)
self.spinner = QtWaitingSpinner(self, centerOnParent=False)
self.grid = QWidgets.QGridLayout()
self.grid.addWidget(self.button, 0, 0)
# self.grid.addWidget(self.spinner,0,1) # ---
self.grid.addWidget(self.spinner, 0, 1, 1, 2) # +++ <---
self.setLayout(self.grid)
self.show()
def toggle_spinner(self):
if self.spinner.isSpinning():
self.spinner.stop()
self.button.setText("Start Spinner") # +
else:
self.spinner.start()
self.button.setText("Stop Spinner") # +
if __name__ == '__main__':
app = QWidgets.QApplication([])
main = Example_Window()
main.resize(170, 70) # +++
sys.exit(app.exec())

Pyqt lunch separate Qtapplications in separate process

So what i would like to do is from the main Qt application start a bunch of separate Qt applications each on separate processes ... do their job then report to the main application when finished.
Could you guys point me in the right direction . I tried with multiprocessing but i get stuck initializing the separate Qt applications
Thank you
Something like this ... which is wrong
import sys
import multiprocessing
from multiprocessing import Pool
from PyQt4 import QtCore, QtGui ,QtNetwork
from PyQt4 import QtWebKit
from PyQt4.QtCore import *
from PyQt4.QtWebKit import *
from PyQt4.QtGui import QApplication
class SimpleWin(QtGui.QWidget):
def __init__(self, parent=None):
super(SimpleWin, self).__init__(parent)
self.buton = QtGui.QPushButton("START")
self.buton.clicked.connect(self.RunJob)
hbox = QtGui.QHBoxLayout()
hbox.addWidget(self.buton)
self.setLayout(hbox)
def RunJob(self):
print "RUUN"
jobs = []
for i in range(5):
p = multiprocessing.Process(target=Render,)
print i
jobs.append(p)
p.start()
class Render(QWebView,multiprocessing.Process):
def __init__(self, prox ):
self.app = QApplication(sys.argv)
QWebPage.__init__(self)
# self.crawl()
self.load(QUrl("http://www.ip-score.com/"))
self.show()
self.app.exec_()
def main():
app = QtGui.QApplication(sys.argv)
browse = SimpleWin()
browse.show()
sys.exit(app.exec_())
if __name__ == '__main__':
main()

Resources