How can I use trio in conjunction with PyQT5? The thing is that my program has interface written using PyQT5, and now I need to run eventloop trio, to work with the network, because I use trio WebSocket to connect to the server. I read that I should use trio.lowlevel.start_guest_run for this purpose. But in the documentation it says that in addition to the trio function I must pass run_sync_soon_threadsafe and done_callback as arguments. The documentation gives an example with asyncio and says that I have to define similar functions for my event_loop, in my case for PyQT. Unfortunately my knowledge is not enough to do it myself.
I wrote a very simple application using PyQT and put in the body of the class an asynchronous function that if it works correctly should change the inscription on the timer every second. In addition you can enter text in the input box and by pressing the button this text will be displayed at the bottom. I did not run the asynchronous function, as that is my question. At best, I expect the answer to my question to be a modified program in which the asynchronous function and the PyQT5 components run in the same thread using trio. Thank you for your reply.
# -*- coding: utf-8 -*-
from PyQt5 import QtCore, QtGui, QtWidgets
import trio
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(804, 595)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.verticalLayoutWidget = QtWidgets.QWidget(self.centralwidget)
self.verticalLayoutWidget.setGeometry(QtCore.QRect(10, 10, 781, 591))
self.verticalLayoutWidget.setObjectName("verticalLayoutWidget")
self.verticalLayout = QtWidgets.QVBoxLayout(self.verticalLayoutWidget)
self.verticalLayout.setContentsMargins(0, 0, 0, 0)
self.verticalLayout.setObjectName("verticalLayout")
spacerItem = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
self.verticalLayout.addItem(spacerItem)
self.lineEdit = QtWidgets.QLineEdit(self.verticalLayoutWidget)
font = QtGui.QFont()
font.setPointSize(20)
self.lineEdit.setFont(font)
self.lineEdit.setObjectName("lineEdit")
self.verticalLayout.addWidget(self.lineEdit)
self.pushButton = QtWidgets.QPushButton(self.verticalLayoutWidget)
font = QtGui.QFont()
font.setPointSize(20)
self.pushButton.setFont(font)
self.pushButton.setObjectName("pushButton")
self.verticalLayout.addWidget(self.pushButton)
self.label = QtWidgets.QLabel(self.verticalLayoutWidget)
font = QtGui.QFont()
font.setPointSize(20)
self.label.setFont(font)
self.label.setAlignment(QtCore.Qt.AlignCenter)
self.label.setObjectName("label")
self.verticalLayout.addWidget(self.label)
spacerItem1 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
self.verticalLayout.addItem(spacerItem1)
self.label_2 = QtWidgets.QLabel(self.verticalLayoutWidget)
font = QtGui.QFont()
font.setPointSize(20)
self.label_2.setFont(font)
self.label_2.setAlignment(QtCore.Qt.AlignCenter)
self.label_2.setObjectName("label_2")
self.verticalLayout.addWidget(self.label_2)
spacerItem2 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
self.verticalLayout.addItem(spacerItem2)
MainWindow.setCentralWidget(self.centralwidget)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
self.pushButton.setText(_translate("MainWindow", "Pushme"))
self.label.setText(_translate("MainWindow", ""))
self.label_2.setText(_translate("MainWindow", "Time"))
class PushMe(Ui_MainWindow):
def __init__(self, MainWindow):
super(PushMe, self).__init__()
self.setupUi(MainWindow)
self.PushMe = MainWindow
self.lineEdit.setPlaceholderText("type something")
self.connect_button()
# self.timer()
def connect_button(self):
self.pushButton.clicked.connect(self.set_text)
def set_text(self):
self.label.setText(self.lineEdit.text())
async def timer(self):
a = 1
while True:
self.label_2.setText(str(a))
a += 1
await trio.sleep(1)
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
MainWindow = QtWidgets.QMainWindow()
ui = PushMe(MainWindow)
MainWindow.show()
sys.exit(app.exec_())
I have to admit that I haven't been keeping up on maintenance on QTrio, but it does mix Qt with Trio. https://qtrio.readthedocs.io/en/stable/ Depending what route you want to go you could either use it as a whole library, or you could just pick out the pieces you want.
https://github.com/altendky/qtrio/blob/43c7ff24c0be2f7a3df86eef3c6cc5dae2f7ffd3/qtrio/_core.py#L649-L657
trio.lowlevel.start_guest_run(
self.trio_main,
async_fn,
args,
run_sync_soon_threadsafe=self.run_sync_soon_threadsafe,
done_callback=self.trio_done,
clock=self.clock, # type: ignore[arg-type]
instruments=self.instruments,
)
https://github.com/altendky/qtrio/blob/43c7ff24c0be2f7a3df86eef3c6cc5dae2f7ffd3/qtrio/_core.py#L672-L683
def run_sync_soon_threadsafe(self, fn: typing.Callable[[], object]) -> None:
"""Helper for the Trio guest to execute a sync function in the Qt host
thread when called from the Trio guest thread. This call will not block waiting
for completion of ``fn`` nor will it return the result of calling ``fn``.
Args:
fn: A no parameter callable.
"""
import qtrio.qt
event = qtrio.qt.ReenterEvent(fn=fn)
self.application.postEvent(self.reenter, event)
Most likely the easiest way is to use qtrio.Runner. Below I have run an asynchronous function using this class by adding just 2 lines of code to an already completed application. In my case this is the answer to my question.
# -*- coding: utf-8 -*-
import qtrio
from PyQt5 import QtCore, QtGui, QtWidgets
import trio
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(804, 595)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.verticalLayoutWidget = QtWidgets.QWidget(self.centralwidget)
self.verticalLayoutWidget.setGeometry(QtCore.QRect(10, 10, 781, 591))
self.verticalLayoutWidget.setObjectName("verticalLayoutWidget")
self.verticalLayout = QtWidgets.QVBoxLayout(self.verticalLayoutWidget)
self.verticalLayout.setContentsMargins(0, 0, 0, 0)
self.verticalLayout.setObjectName("verticalLayout")
spacerItem = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
self.verticalLayout.addItem(spacerItem)
self.lineEdit = QtWidgets.QLineEdit(self.verticalLayoutWidget)
font = QtGui.QFont()
font.setPointSize(20)
self.lineEdit.setFont(font)
self.lineEdit.setObjectName("lineEdit")
self.verticalLayout.addWidget(self.lineEdit)
self.pushButton = QtWidgets.QPushButton(self.verticalLayoutWidget)
font = QtGui.QFont()
font.setPointSize(20)
self.pushButton.setFont(font)
self.pushButton.setObjectName("pushButton")
self.verticalLayout.addWidget(self.pushButton)
self.label = QtWidgets.QLabel(self.verticalLayoutWidget)
font = QtGui.QFont()
font.setPointSize(20)
self.label.setFont(font)
self.label.setAlignment(QtCore.Qt.AlignCenter)
self.label.setObjectName("label")
self.verticalLayout.addWidget(self.label)
spacerItem1 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
self.verticalLayout.addItem(spacerItem1)
self.label_2 = QtWidgets.QLabel(self.verticalLayoutWidget)
font = QtGui.QFont()
font.setPointSize(20)
self.label_2.setFont(font)
self.label_2.setAlignment(QtCore.Qt.AlignCenter)
self.label_2.setObjectName("label_2")
self.verticalLayout.addWidget(self.label_2)
spacerItem2 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
self.verticalLayout.addItem(spacerItem2)
MainWindow.setCentralWidget(self.centralwidget)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
self.pushButton.setText(_translate("MainWindow", "Pushme"))
self.label.setText(_translate("MainWindow", ""))
self.label_2.setText(_translate("MainWindow", "Time"))
class PushMe(Ui_MainWindow):
def __init__(self, MainWindow):
super(PushMe, self).__init__()
self.setupUi(MainWindow)
self.PushMe = MainWindow
self.lineEdit.setPlaceholderText("type something")
self.connect_button()
# self.timer()
def connect_button(self):
self.pushButton.clicked.connect(self.set_text)
def set_text(self):
self.label.setText(self.lineEdit.text())
async def timer(self):
a = 1
while True:
self.label_2.setText(str(a))
a += 1
await trio.sleep(1)
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
MainWindow = QtWidgets.QMainWindow()
ui = PushMe(MainWindow)
MainWindow.show()
trio_loop = qtrio.Runner(application=app)
trio_loop.run(ui.timer)
sys.exit(app.exec_())
Related
I have a while loop which is set to True , inside the loop I want to write some text to TextBrowser but no matter what I try , self.textEdit.setText or self.textEdit.append doesn't work.
I tried to change also label or even line text but without success.
when I take this out of the while loop the text appear in the text browser.
I treid using Threads but even when the thread is started the text does not appear in the text browser. here is the code i have.
import socket
import socket as socket_library
import threading
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(1014, 920)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.radioButton = QtWidgets.QRadioButton(self.centralwidget)
self.radioButton.setGeometry(QtCore.QRect(180, 180, 141, 41))
font = QtGui.QFont()
font.setBold(True)
font.setWeight(75)
self.radioButton.setFont(font)
self.radioButton.setObjectName("radioButton")
self.textEdit = QtWidgets.QTextEdit(self.centralwidget)
self.textEdit.setGeometry(QtCore.QRect(180, 230, 691, 411))
self.textEdit.setStyleSheet("background-color: rgb(0, 0, 0);\n"
"color: rgb(0, 255, 0);")
self.textEdit.setObjectName("textEdit")
self.label = QtWidgets.QLabel(self.centralwidget)
self.label.setGeometry(QtCore.QRect(210, 80, 571, 51))
font = QtGui.QFont()
font.setPointSize(16)
font.setBold(True)
font.setWeight(75)
self.label.setFont(font)
self.label.setAlignment(QtCore.Qt.AlignCenter)
self.label.setObjectName("label")
MainWindow.setCentralWidget(self.centralwidget)
self.statusbar = QtWidgets.QStatusBar(MainWindow)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
self.radioButton.setText(_translate("MainWindow", "Start Server"))
self.label.setText(_translate("MainWindow",
"<html><head/><body><p><span style=\" color:#00557f;\">Lots of Trips Server</span></p></body></html>"))
self.radioButton.clicked.connect(self.check_readio_button)
def check_readio_button(self):
if self.radioButton.isChecked():
self.activate_server()
def activate_server(self):
hostname = socket.gethostname()
IPaddress = socket.gethostbyname(hostname)
port = 45971
server_socket = socket_library.socket(socket_library.AF_INET, socket_library.SOCK_DGRAM)
server_socket.bind((IPaddress, port))
while True:
try:
message, address = server_socket.recvfrom(1024)
except ConnectionError:
print("Connection with server is closed.")
break
server_socket.sendto("Thank you for connection.".encode("UTF-8"), address)
answer = message.decode("UTF-8")
self.thread1 = threading.Thread(target=self.task(), args=(None,))
self.thread1.start()
self.thread1.join()
server_socket.close()
def task(self):
self.textEdit.setText("This is from another thread")
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
MainWindow = QtWidgets.QMainWindow()
ui = Ui_MainWindow()
ui.setupUi(MainWindow)
MainWindow.show()
sys.exit(app.exec_())
Thread.start()
Thread.join()
I think "append" is working, but you need to process pending events and refresh the GUI by calling QApplication.processEvents()
LOGIN.py
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_LOGIN_PAGE(object):
def setupUi(self, LOGIN_PAGE):
LOGIN_PAGE.setObjectName("LOGIN_PAGE")
LOGIN_PAGE.resize(1909, 995)
self.centralwidget = QtWidgets.QWidget(LOGIN_PAGE)
self.centralwidget.setObjectName("centralwidget")
self.frame = QtWidgets.QFrame(self.centralwidget)
self.frame.setGeometry(QtCore.QRect(690, 220, 501, 571))
font = QtGui.QFont()
font.setFamily("Cambria Math")
font.setPointSize(11)
self.frame.setFont(font)
self.frame.setStyleSheet("QFrame{\n""background:rgb(255, 250, 175);\n""border-radius:30px;\n"
"}\n""\n""QLineEdit{\n""border-radius:10px;\n""}\n""\n""QPushButton{\n""background:#03a9f4;\n"
"border-radius:10px;}")
self.frame.setFrameShape(QtWidgets.QFrame.StyledPanel)
self.frame.setFrameShadow(QtWidgets.QFrame.Raised)
self.frame.setObjectName("frame")
self.pushButton = QtWidgets.QPushButton(self.frame)
self.pushButton.setGeometry(QtCore.QRect(30, 360, 441, 81))
font = QtGui.QFont()
font.setFamily("Cambria")
font.setPointSize(14)
font.setBold(True)
font.setWeight(75)
self.pushButton.setFont(font)
self.pushButton.setObjectName("pushButton")
self.pushButton_2 = QtWidgets.QPushButton(self.frame)
self.pushButton_2.setGeometry(QtCore.QRect(130, 480, 241, 41))
font = QtGui.QFont()
font.setFamily("Gill Sans MT")
font.setPointSize(10)
self.pushButton_2.setFont(font)
self.pushButton_2.setObjectName("pushButton_2")
self.lineEdit = QtWidgets.QLineEdit(self.frame)
self.lineEdit.setGeometry(QtCore.QRect(30, 260, 441, 51))
font = QtGui.QFont()
font.setFamily("Cambria Math")
font.setPointSize(12)
self.lineEdit.setFont(font)
self.lineEdit.setText("")
self.lineEdit.setEchoMode(QtWidgets.QLineEdit.Password)
self.lineEdit.setObjectName("lineEdit")
self.lineEdit_2 = QtWidgets.QLineEdit(self.frame)
self.lineEdit_2.setGeometry(QtCore.QRect(30, 110, 441, 51))
font = QtGui.QFont()
font.setFamily("Cambria Math")
font.setPointSize(12)
self.lineEdit_2.setFont(font)
self.lineEdit_2.setText("")
self.lineEdit_2.setObjectName("lineEdit_2")
self.label = QtWidgets.QLabel(self.frame)
self.label.setGeometry(QtCore.QRect(40, 60, 231, 41))
font = QtGui.QFont()
font.setFamily("Cambria Math")
font.setPointSize(11)
self.label.setFont(font)
self.label.setObjectName("label")
self.label_2 = QtWidgets.QLabel(self.frame)
self.label_2.setGeometry(QtCore.QRect(40, 210, 231, 41))
font = QtGui.QFont()
font.setFamily("Cambria Math")
font.setPointSize(11)
self.label_2.setFont(font)
self.label_2.setObjectName("label_2")
LOGIN_PAGE.setCentralWidget(self.centralwidget)
self.statusbar = QtWidgets.QStatusBar(LOGIN_PAGE)
self.statusbar.setObjectName("statusbar")
LOGIN_PAGE.setStatusBar(self.statusbar)
self.retranslateUi(LOGIN_PAGE)
QtCore.QMetaObject.connectSlotsByName(LOGIN_PAGE)
def retranslateUi(self, LOGIN_PAGE):
_translate = QtCore.QCoreApplication.translate
LOGIN_PAGE.setWindowTitle(_translate("LOGIN_PAGE", "MainWindow"))
self.pushButton.setText(_translate("LOGIN_PAGE", "LOGIN"))
self.pushButton_2.setText(_translate("LOGIN_PAGE", "Forget Password"))
self.lineEdit.setPlaceholderText(_translate("LOGIN_PAGE", "PASSWORD"))
self.lineEdit_2.setPlaceholderText(_translate("LOGIN_PAGE", "USERNAME"))
self.label.setText(_translate("LOGIN_PAGE", "USERNAME :"))
self.label_2.setText(_translate("LOGIN_PAGE", "PASSWORD :"))
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
LOGIN_PAGE = QtWidgets.QMainWindow()
ui = Ui_LOGIN_PAGE()
ui.setupUi(LOGIN_PAGE)
LOGIN_PAGE.show()
sys.exit(app.exec_())
LOGINCLICK.py
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(505, 256)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.frame = QtWidgets.QFrame(self.centralwidget)
self.frame.setGeometry(QtCore.QRect(-1, -1, 501, 251))
self.frame.setStyleSheet("QFrame{\n""background:rgb(248, 255, 185);}\n""\n""QPushButton{\n"
"background:#03a9f4;\n""border-radius:10px;}")
self.frame.setFrameShape(QtWidgets.QFrame.StyledPanel)
self.frame.setFrameShadow(QtWidgets.QFrame.Raised)
self.frame.setObjectName("frame")
self.pushButton1 = QtWidgets.QPushButton(self.frame)
self.pushButton1.setGeometry(QtCore.QRect(70, 90, 151, 51))
self.pushButton1.setObjectName("pushButton1")
self.pushButton1_2 = QtWidgets.QPushButton(self.frame)
self.pushButton1_2.setGeometry(QtCore.QRect(280, 90, 151, 51))
self.pushButton1_2.setObjectName("pushButton1_2")
MainWindow.setCentralWidget(self.centralwidget)
self.statusbar = QtWidgets.QStatusBar(MainWindow)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
self.pushButton1.setText(_translate("MainWindow", "LOGIN"))
self.pushButton1_2.setText(_translate("MainWindow", "REGISTRATION"))
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
MainWindow = QtWidgets.QMainWindow()
ui = Ui_MainWindow()
ui.setupUi(MainWindow)
MainWindow.show()
sys.exit(app.exec_())
How to switch from LOGINCLICK.py to LOGIN.py by clicking a button?
First of all, and this is more a matter of concept, you're not going to "switch" between those files, but between the instances of the classes that are in those files.
Second, you should create a file that acts as a "main" script, which is the file that you'll actually run from python; this is a general rule for programs that use multiple files as "modules", and is almost mandatory for PyQt when using files generated by pyuic; note that you should also never modify the contents of those files, but import them as python modules (read more about using Designer).
Recreate the files with pyuic, then create a new file that will look like this:
from PyQt5 import QtWidgets
from LOGINCLICK import Ui_MainWindow
from LOGIN import Ui_LOGIN_PAGE
class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
def __init__(self):
super().__init__()
self.setupUi(self)
self.pushButton1.clicked.connect(self.showLogin)
def showLogin(self):
self.loginWindow = LoginWindow()
self.loginWindow.show()
class LoginWindow(QtWidgets.QMainWindow, Ui_LOGIN_PAGE):
def __init__(self):
super().__init__()
self.setupUi(self)
if __name__ == '__main__':
import sys
app = QtWidgets.QApplication(sys.argv)
mainWindow = MainWindow()
mainWindow.show()
sys.exit(app.exec_())
Now, some suggestions:
avoid fixed geometries in any case, and use layout managers instead (like QGridLayout, QHBoxLayout or QVBoxLayout) so that the contents of the windows will always adjust to the available size, otherwise some of the widgets might become unaccessible if the user resizes the window to a smaller size than you decided (there are also other reasons for this, but this is the most important);
don't use uppercase names for files or variables; read more about naming conventions in the Style Guide for Python Code;
a login window should probably be "modal" (shown over the current windows and avoiding interaction with them until the login window is closed); you can use a QDialog for this: from Designer create a new empty dialog, copy the elements of your current login form and paste them to the new dialog (or select all of them and use ctrl+drag), save and generate the file with pyuic, then change the above code considering the following modifications:
class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
#...
def showLogin(self):
self.loginWindow = LoginWindow(self)
self.loginWindow.exec_()
class LoginWindow(QtWidgets.QDialog, Ui_LOGIN_PAGE):
def __init__(self, parent=None):
super().__init__()
self.setupUi(self)
Hello dear Users of stackoverflow
Introduction:
I am kind of new to Python and want to build a touch GUI for my Raspberry Pi with PyQt5. Therefore, I use the QtDesigner to build up .ui files on Windows 7. After that, the files are translated to .py files using "pyuic5 -x file.ui -o file.py" in the LXTerminal of the Pi.
My GUI:
I need to build up one output window (MainWindow) with a label and a push button, which opens up another window (I chose Dialog) for input. The input window has a spin box to set the value and a horizontal slider for bigger value steps. At the bottom of the window is a push button, which sets the spin box value as global variable and closes the Input window again.
The problem:
I want the push button of the input window that closes this window to also refresh the output label of the MainWindow, so that it shows the new value.
Pictures:
I am not allowed to embed Pictures of my GUI yet, so please see the following links.
MainWindow
InputWindow
InputWindow with Connections between slider and spin box
My Code:
The following code is a simple example and has everything working except the refresh of the Label. Please help me to get this work, even if it might be very simple for advanced and professional developers. I spent days on trying and googling for this and got lots of more complicated things working.
Best wishes,
RaspiManu
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from PyQt5 import QtCore, QtGui, QtWidgets
value = 0
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(890, 600)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.label = QtWidgets.QLabel(self.centralwidget)
self.label.setGeometry(QtCore.QRect(180, 100, 500, 250))
font = QtGui.QFont()
font.setPointSize(20)
self.label.setFont(font)
self.label.setStyleSheet("background-color: rgb(255, 255, 255);")
self.label.setAlignment(QtCore.Qt.AlignCenter)
self.label.setObjectName("label")
self.pushButton = QtWidgets.QPushButton(self.centralwidget)
self.pushButton.setGeometry(QtCore.QRect(180, 370, 500, 100))
font = QtGui.QFont()
font.setPointSize(15)
self.pushButton.setFont(font)
self.pushButton.setObjectName("pushButton")
############
self.pushButton.clicked.connect(self.OpenInput)
############
MainWindow.setCentralWidget(self.centralwidget)
self.statusbar = QtWidgets.QStatusBar(MainWindow)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
self.label.setText(_translate("MainWindow", "Value"))
self.pushButton.setText(_translate("MainWindow", "Go to input window"))
##############################
# Show second window for input
def OpenInput(self, MainWindow):
Dialog.show()
##############################
class Ui_Dialog(object):
def setupUi(self, Dialog):
Dialog.setObjectName("Dialog")
Dialog.resize(889, 598)
self.spinBox = QtWidgets.QSpinBox(Dialog)
self.spinBox.setGeometry(QtCore.QRect(210, 170, 471, 141))
font = QtGui.QFont()
font.setPointSize(33)
self.spinBox.setFont(font)
self.spinBox.setAlignment(QtCore.Qt.AlignCenter)
self.spinBox.setObjectName("spinBox")
self.horizontalSlider = QtWidgets.QSlider(Dialog)
self.horizontalSlider.setGeometry(QtCore.QRect(209, 360, 471, 61))
self.horizontalSlider.setOrientation(QtCore.Qt.Horizontal)
self.horizontalSlider.setObjectName("horizontalSlider")
self.pushButton = QtWidgets.QPushButton(Dialog)
self.pushButton.setGeometry(QtCore.QRect(310, 460, 271, 71))
font = QtGui.QFont()
font.setPointSize(13)
self.pushButton.setFont(font)
self.pushButton.setObjectName("pushButton")
############
self.pushButton.clicked.connect(self.CloseAndRefresh)
############
self.label = QtWidgets.QLabel(Dialog)
self.label.setGeometry(QtCore.QRect(210, 40, 471, 91))
font = QtGui.QFont()
font.setPointSize(24)
font.setBold(True)
font.setWeight(75)
self.label.setFont(font)
self.label.setAlignment(QtCore.Qt.AlignCenter)
self.label.setObjectName("label")
self.retranslateUi(Dialog)
self.horizontalSlider.valueChanged['int'].connect(self.spinBox.setValue)
self.spinBox.valueChanged['int'].connect(self.horizontalSlider.setValue)
QtCore.QMetaObject.connectSlotsByName(Dialog)
def retranslateUi(self, Dialog):
_translate = QtCore.QCoreApplication.translate
Dialog.setWindowTitle(_translate("Dialog", "Dialog"))
self.pushButton.setText(_translate("Dialog", "Back to first Window"))
self.label.setText(_translate("Dialog", "Value"))
#######################################################
# Close second window and refresh label on first window
def CloseAndRefresh(self):
global value
value = self.spinBox.value()
print(value) #checking input
##################################################
# The refresh of the outputting label on the #
# MainWindow should be started at this position. #
##################################################
Dialog.close()
#######################################################
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
MainWindow = QtWidgets.QMainWindow()
ui = Ui_MainWindow()
ui.setupUi(MainWindow)
MainWindow.show()
Dialog = QtWidgets.QDialog()
dia = Ui_Dialog()
dia.setupUi(Dialog)
sys.exit(app.exec_())
Try it:
from PyQt5 import QtCore, QtGui, QtWidgets
value = 0
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(890, 600)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.label = QtWidgets.QLabel(self.centralwidget)
self.label.setGeometry(QtCore.QRect(180, 100, 500, 250))
font = QtGui.QFont()
font.setPointSize(20)
self.label.setFont(font)
self.label.setStyleSheet("background-color: rgb(255, 255, 255);")
self.label.setAlignment(QtCore.Qt.AlignCenter)
self.label.setObjectName("label")
self.pushButton = QtWidgets.QPushButton(self.centralwidget)
self.pushButton.setGeometry(QtCore.QRect(180, 370, 500, 100))
font = QtGui.QFont()
font.setPointSize(15)
self.pushButton.setFont(font)
self.pushButton.setObjectName("pushButton")
############
self.pushButton.clicked.connect(self.OpenInput)
############
MainWindow.setCentralWidget(self.centralwidget)
self.statusbar = QtWidgets.QStatusBar(MainWindow)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
self.label.setText(_translate("MainWindow", "Value"))
self.pushButton.setText(_translate("MainWindow", "Go to input window"))
##############################
# Show second window for input
def OpenInput(self, MainWindow):
Dialog.show()
##############################
# +++
def labelText(self, MainWindow, value):
self.label.setText(str(value))
class Ui_Dialog(object):
def setupUi(self, Dialog):
Dialog.setObjectName("Dialog")
Dialog.resize(889, 598)
self.spinBox = QtWidgets.QSpinBox(Dialog)
self.spinBox.setGeometry(QtCore.QRect(210, 170, 471, 141))
font = QtGui.QFont()
font.setPointSize(33)
self.spinBox.setFont(font)
self.spinBox.setAlignment(QtCore.Qt.AlignCenter)
self.spinBox.setObjectName("spinBox")
self.horizontalSlider = QtWidgets.QSlider(Dialog)
self.horizontalSlider.setGeometry(QtCore.QRect(209, 360, 471, 61))
self.horizontalSlider.setOrientation(QtCore.Qt.Horizontal)
self.horizontalSlider.setObjectName("horizontalSlider")
self.pushButton = QtWidgets.QPushButton(Dialog)
self.pushButton.setGeometry(QtCore.QRect(310, 460, 271, 71))
font = QtGui.QFont()
font.setPointSize(13)
self.pushButton.setFont(font)
self.pushButton.setObjectName("pushButton")
############
self.pushButton.clicked.connect(self.CloseAndRefresh)
############
self.label = QtWidgets.QLabel(Dialog)
self.label.setGeometry(QtCore.QRect(210, 40, 471, 91))
font = QtGui.QFont()
font.setPointSize(24)
font.setBold(True)
font.setWeight(75)
self.label.setFont(font)
self.label.setAlignment(QtCore.Qt.AlignCenter)
self.label.setObjectName("label")
self.retranslateUi(Dialog)
self.horizontalSlider.valueChanged['int'].connect(self.spinBox.setValue)
self.spinBox.valueChanged['int'].connect(self.horizontalSlider.setValue)
QtCore.QMetaObject.connectSlotsByName(Dialog)
def retranslateUi(self, Dialog):
_translate = QtCore.QCoreApplication.translate
Dialog.setWindowTitle(_translate("Dialog", "Dialog"))
self.pushButton.setText(_translate("Dialog", "Back to first Window"))
self.label.setText(_translate("Dialog", "Value"))
#######################################################
# Close second window and refresh label on first window
def CloseAndRefresh(self):
global value
value = self.spinBox.value()
print(value) #checking input
# +++
ui.labelText(MainWindow, value)
##################################################
# The refresh of the outputting label on the #
# MainWindow should be started at this position. #
##################################################
Dialog.close()
#######################################################
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
MainWindow = QtWidgets.QMainWindow()
ui = Ui_MainWindow()
ui.setupUi(MainWindow)
MainWindow.show()
Dialog = QtWidgets.QDialog()
dia = Ui_Dialog()
dia.setupUi(Dialog)
sys.exit(app.exec_())
I have made a UI which has various actions in three toolbars. I'm trying to make the font of one action bold when it is pressed and released by mouse. I know how to make the font bold one-by-one. But I'm going to add tens of actions in those three toolbars. How would I be able to do this? Can anyone help me?
Thank you very much.
The main function does make the font of action1 bold.
Main function:
from uitest import Ui_MainWindow
from PyQt5.QtWidgets import QMainWindow
class window(QMainWindow):
def __init__(self, parent=None):
super(window, self).__init__(parent)
self.ui = Ui_MainWindow()
self.ui.setupUi(self)
myFont = QtGui.QFont()
myFont.setBold(True)
self.ui.Action1.setFont(myFont)
if __name__ == "__main__":
app = QApplication([])
gui = window()
gui.show()
app.exec_()
UI code
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(800, 600)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.pushButton = QtWidgets.QPushButton(self.centralwidget)
self.pushButton.setGeometry(QtCore.QRect(120, 330, 151, 71))
self.pushButton.setObjectName("pushButton")
self.pushButton_2 = QtWidgets.QPushButton(self.centralwidget)
self.pushButton_2.setGeometry(QtCore.QRect(360, 330, 151, 71))
self.pushButton_2.setObjectName("pushButton_2")
self.textEdit = QtWidgets.QTextEdit(self.centralwidget)
self.textEdit.setGeometry(QtCore.QRect(160, 80, 321, 181))
self.textEdit.setObjectName("textEdit")
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 800, 21))
self.menubar.setObjectName("menubar")
MainWindow.setMenuBar(self.menubar)
self.statusbar = QtWidgets.QStatusBar(MainWindow)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)
self.toolBar1 = QtWidgets.QToolBar(MainWindow)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.toolBar1.sizePolicy().hasHeightForWidth())
self.toolBar1.setSizePolicy(sizePolicy)
font = QtGui.QFont()
font.setPointSize(14)
self.toolBar1.setFont(font)
self.toolBar1.setObjectName("toolBar1")
MainWindow.addToolBar(QtCore.Qt.TopToolBarArea, self.toolBar1)
self.toolBar = QtWidgets.QToolBar(MainWindow)
font = QtGui.QFont()
font.setPointSize(12)
self.toolBar.setFont(font)
self.toolBar.setObjectName("toolBar")
MainWindow.addToolBar(QtCore.Qt.TopToolBarArea, self.toolBar)
MainWindow.insertToolBarBreak(self.toolBar)
self.toolBar_2 = QtWidgets.QToolBar(MainWindow)
font = QtGui.QFont()
font.setPointSize(10)
self.toolBar_2.setFont(font)
self.toolBar_2.setObjectName("toolBar_2")
MainWindow.addToolBar(QtCore.Qt.TopToolBarArea, self.toolBar_2)
MainWindow.insertToolBarBreak(self.toolBar_2)
self.Action1 = QtWidgets.QAction(MainWindow)
self.Action1.setObjectName("Action1")
self.Action2 = QtWidgets.QAction(MainWindow)
self.Action2.setObjectName("Action2")
self.Action3 = QtWidgets.QAction(MainWindow)
self.Action3.setObjectName("Action3")
self.Action4 = QtWidgets.QAction(MainWindow)
self.Action4.setObjectName("Action4")
self.Action5 = QtWidgets.QAction(MainWindow)
self.Action5.setObjectName("Action5")
self.Action6 = QtWidgets.QAction(MainWindow)
self.Action6.setObjectName("Action6")
self.Action7 = QtWidgets.QAction(MainWindow)
self.Action7.setObjectName("Action7")
self.Action8 = QtWidgets.QAction(MainWindow)
self.Action8.setObjectName("Action8")
self.Action9 = QtWidgets.QAction(MainWindow)
self.Action9.setObjectName("Action9")
self.toolBar1.addAction(self.Action1)
self.toolBar1.addSeparator()
self.toolBar1.addAction(self.Action2)
self.toolBar1.addSeparator()
self.toolBar1.addAction(self.Action3)
self.toolBar.addAction(self.Action4)
self.toolBar.addSeparator()
self.toolBar.addAction(self.Action5)
self.toolBar.addSeparator()
self.toolBar.addAction(self.Action6)
self.toolBar_2.addAction(self.Action7)
self.toolBar_2.addSeparator()
self.toolBar_2.addAction(self.Action8)
self.toolBar_2.addSeparator()
self.toolBar_2.addAction(self.Action9)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
self.pushButton.setText(_translate("MainWindow", "PushButton"))
self.pushButton_2.setText(_translate("MainWindow", "PushButton"))
self.toolBar1.setWindowTitle(_translate("MainWindow", "toolBar"))
self.toolBar.setWindowTitle(_translate("MainWindow", "toolBar"))
self.toolBar_2.setWindowTitle(_translate("MainWindow", "toolBar_2"))
self.Action1.setText(_translate("MainWindow", "Action1"))
self.Action2.setText(_translate("MainWindow", "Action2"))
self.Action3.setText(_translate("MainWindow", "Action3"))
self.Action4.setText(_translate("MainWindow", "Action4"))
self.Action5.setText(_translate("MainWindow", "Action5"))
self.Action6.setText(_translate("MainWindow", "Action6"))
self.Action7.setText(_translate("MainWindow", "Action7"))
self.Action8.setText(_translate("MainWindow", "Action8"))
self.Action9.setText(_translate("MainWindow", "Action9"))
UI is created by PyQt5 designer.
One way to do this would be to connect to the actionTriggered signal of each toolbar, which sends the action that was clicked. Assuming you only want one action bold at a time, you can then use this to turn on bold for the current action and turn off bold for the previous action (if there is one):
class window(QMainWindow):
def __init__(self, parent=None):
...
for toolbar in self.findChildren(QtWidgets.QToolBar):
toolbar.actionTriggered.connect(self.setBoldAction)
def setBoldAction(self, target, toolbar=None):
if toolbar is None:
toolbar = self.sender()
for action in toolbar.actions():
if not action.isSeparator():
font = action.font()
font.setBold(action is target)
action.setFont(font)
If you want to set the bold action programmatically, you can also do:
self.setBoldAction(action, toolbar)
I wrote a small PyQt program based on an example from a book. I edited the code to add some niceties. Below is my code:
from __future__ import division
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
import sys
class Ui_MainWindow(QWidget):
def __init__(self):
QWidget.__init__(self)
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(800, 600)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.verticalLayoutWidget = QtWidgets.QWidget(self.centralwidget)
self.verticalLayoutWidget.setGeometry(QtCore.QRect(9, 9, 781, 461))
self.verticalLayoutWidget.setObjectName("verticalLayoutWidget")
self.verticalLayout = QtWidgets.QVBoxLayout(self.verticalLayoutWidget)
self.verticalLayout.setObjectName("verticalLayout")
self.textBrowser = QtWidgets.QTextBrowser(self.verticalLayoutWidget)
self.textBrowser.setObjectName("textBrowser")
self.verticalLayout.addWidget(self.textBrowser)
self.horizontalLayoutWidget = QtWidgets.QWidget(self.centralwidget)
self.horizontalLayoutWidget.setGeometry(QtCore.QRect(10, 480, 781, 80))
self.horizontalLayoutWidget.setObjectName("horizontalLayoutWidget")
self.horizontalLayout_2 = QtWidgets.QHBoxLayout(self.horizontalLayoutWidget)
self.horizontalLayout_2.setObjectName("horizontalLayout_2")
self.label = QtWidgets.QLabel(self.horizontalLayoutWidget)
font = QtGui.QFont()
font.setPointSize(16)
self.label.setFont(font)
self.label.setObjectName("label")
self.horizontalLayout_2.addWidget(self.label)
self.lineEdit = QtWidgets.QLineEdit(self.horizontalLayoutWidget)
self.lineEdit.setBaseSize(QtCore.QSize(0, 0))
font = QtGui.QFont()
font.setPointSize(12)
self.lineEdit.setFont(font)
self.lineEdit.setText("")
self.lineEdit.setObjectName("lineEdit")
self.horizontalLayout_2.addWidget(self.lineEdit)
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 800, 21))
self.menubar.setObjectName("menubar")
self.menuFile = QtWidgets.QMenu(self.menubar)
self.menuFile.setObjectName("menuFile")
MainWindow.setMenuBar(self.menubar)
self.actionQuit = QtWidgets.QAction(MainWindow)
self.actionQuit.setObjectName("actionQuit")
self.menuFile.addAction(self.actionQuit)
self.menubar.addAction(self.menuFile.menuAction())
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
self.label.setText(_translate("MainWindow", "Expression:"))
self.menuFile.setTitle(_translate("MainWindow", "File"))
self.actionQuit.setText(_translate("MainWindow", "Quit (Ctrl+Q)"))
self.actionQuit.setShortcut(_translate("MainWindow", "Ctrl+Q"))
self.lineEdit.setFocus()
self.connect(self.lineEdit, self.updateUi)
self.setWindowTitle("Calculate")
def updateUi(self):
try:
text = unicode(self.lineEdit.text())
self.browser.append("%s = <b>%s</b>" % (text,eval(text)))
except:
self.browser.append("<font color=red>Invalid Expression</font>")
if __name__ == '__main__':
app = QApplication(sys.argv)
window = Ui_MainWindow()
window.show()
sys.exit(app.exec_())
Output:
But when I execute this file I only get a blank window without any widgets inside it. What is the error in my code?
You defined setupUi() function but I don't see you executing it anywhere. You should expand your __init__ with:
class Ui_MainWindow(QWidget):
def __init__(self):
QWidget.__init__(self)
self.setupUi(your_main_window)