I am developing an application in pyqt5 and I ran into one problem.
There is a script that receives data, and in pyqt5 in the line "main_text.setText (str (TEXT))" I output them, and in the format "str" But the script itself receives and outputs data every 0.2s, but in the line "main_text.setText (str (TEXT))" they are not updated.
Tried through the time sleep function, the app doesn't work,
what method in pyqt5 can be used to output different data to the same set text ?
My code :
from PyQt5 import QtWidgets
from PyQt5.QtWidgets import QApplication, QMainWindow
import sys
import MetaTrader5 as mt5
import time
mt5.initialize()
ticket_info = mt5.symbol_info_tick("EURUSD")._asdict()
bid_usd = mt5.symbol_info_tick("EURUSD").bid
def applecation():
app = QApplication(sys.argv)
window = QMainWindow()
window.setWindowTitle('Test Programm')
window.setGeometry(300, 250, 350, 200)
main_text = QtWidgets.QLabel(window)
main_text.setText(str(bid_usd))
main_text.move(100,100)
main_text.adjustSize()
window.show()
sys.exit(app.exec_())
if __name__ == "__main__":
applecation()
You are invoking the symbol_info_tick method only once so you will only get a data, if you want to get that information every T seconds then you must use a while True that is executed in a secondary thread so that it does not block the GUI and send the information through of signals.
import sys
import threading
import time
from PyQt5.QtCore import QObject, pyqtSignal
from PyQt5.QtWidgets import QApplication, QLabel, QMainWindow
import MetaTrader5 as mt5
class MetaTrader5Worker(QObject):
dataChanged = pyqtSignal(str)
def start(self):
threading.Thread(target=self._execute, daemon=True).start()
def _execute(self):
mt5.initialize()
while True:
bid_usd = mt5.symbol_info_tick("EURUSD").bid
self.dataChanged.emit(str(bid_usd))
time.sleep(0.5)
class MainWindow(QMainWindow):
def __init__(self, parent=None):
super().__init__(parent)
self.label = QLabel(self)
self.setWindowTitle("Test Programm")
self.setGeometry(300, 250, 350, 200)
def handle_data_changed(self, text):
self.label.setText(text)
self.label.adjustSize()
def main():
app = QApplication(sys.argv)
window = MainWindow()
window.show()
worker = MetaTrader5Worker()
worker.dataChanged.connect(window.handle_data_changed)
worker.start()
sys.exit(app.exec_())
if __name__ == "__main__":
main()
You can use threading , it's easier to understand than QThreads
from PyQt5 import QtWidgets
from PyQt5.QtWidgets import QApplication, QMainWindow
import threading
import sys
import MetaTrader5 as mt5
import time
mt5.initialize()
ticket_info = mt5.symbol_info_tick("EURUSD")._asdict()
bid_usd = mt5.symbol_info_tick("EURUSD").bid
def applecation():
app = QApplication(sys.argv)
window = QMainWindow()
window.setWindowTitle('Test Programm')
window.setGeometry(300, 250, 350, 200)
main_text = QtWidgets.QLabel(window)
main_text.move(100,100)
main_text.adjustSize()
def update_text():
while True:
main_text.setText(str(bid_usd))
time.sleep(0.2)
t1 = threading.Thread(target = update_text())
t1.start()
window.show()
sys.exit(app.exec_())
if __name__ == "__main__":
applecation()
Related
I'm learning how to use PyQt correctly.
Trying to make a window Class with a button that prints a line.
import sys
from PyQt5.QtWidgets import QApplication, QWidget, QLabel, QPushButton
from PyQt5.QtGui import QIcon
from PyQt5.QtCore import pyqtSlot
class Window:
def __init__(self, args):
#initializes PyQt
self.app = QApplication(args)
self.widget = QWidget()
self.widget.setWindowTitle("PyQt5 Example")
#create label
self.textLabel = QLabel(self.widget)
self.textLabel.setText("Hello World!")
self.textLabel.move(110,85)
#create button
self.button = QPushButton(self.widget)
self.button.setText("Click me!")
self.button.move(64,32)
#connect button to a method
self.button.clicked.connect(buttonClicked)
#set starting position on monitor (50, 50) and window size (320, 200)
self.widget.setGeometry(50,50,320,200)
#show window
self.widget.show()
sys.exit(app.exec_())
def buttonClicked(self):
print("Button clicked!")
if __name__ == '__main__':
print(sys.argv)
app = Window(sys.argv)
When I run the code I get, NameError: name 'buttonClicked' is not defined
Double checking all indentation and object syntax it's not apparent to me what is wrong. What's weirder is that such syntax works completely fine when outside of a class.
E.g the following code returns no NameError,
import sys
from PyQt5.QtWidgets import QApplication, QWidget, QPushButton
from PyQt5.QtGui import QIcon
from PyQt5.QtCore import pyqtSlot
def window():
app = QApplication(sys.argv)
widget = QWidget()
button1 = QPushButton(widget)
button1.setText("Button1")
button1.move(64,32)
button1.clicked.connect(button1_clicked)
button2 = QPushButton(widget)
button2.setText("Button2")
button2.move(64,64)
button2.clicked.connect(button2_clicked)
widget.setGeometry(50,50,320,200)
widget.setWindowTitle("PyQt5 Button Click Example")
widget.show()
sys.exit(app.exec_())
def button1_clicked():
print("Button 1 clicked")
def button2_clicked():
print("Button 2 clicked")
if __name__ == '__main__':
window()
I wasn't properly referencing the method. when calling self.button.clicked.connect(buttonClicked).
What is required is self.button.clicked.connect(self.buttonClicked)
Keep gif running while GUI starts. Is that possible? I have read many reporitys but none with the true and understandable answer.
I have prepared a code example that shows the problem.
import sys
from PyQt5.QtWidgets import QMainWindow, QLabel, QGridLayout, QWidget
from PyQt5 import QtWidgets
from PyQt5.QtGui import QMovie
from PyQt5.QtCore import QSize, QThread
class Main_Window(QMainWindow):
def __init__(self):
QMainWindow.__init__(self)
self.setMinimumSize(QSize(500, 500))
self.setWindowTitle("Main Window")
centralWidget = QWidget(self)
self.setCentralWidget(centralWidget)
gridLayout = QGridLayout(self)
centralWidget.setLayout(gridLayout)
gif = QLabel(self)
gif.setGeometry(0,0,500,500)
self.movie = QMovie(r"C:\Users\...\Pictures\Icon_LOAD.gif")
gif.setMovie(self.movie)
self.movie.start()
# #Call event handler to process the queue, but it is shocking, dirty and unsuitable
#app.processEvents()
self.show()
for i in range(0,1000000):
print(i)
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
MainWin = Main_Window()
sys.exit(app.exec_())
Now it works smooth
import sys
from PyQt5.QtWidgets import QMainWindow, QLabel, QGridLayout, QWidget
from PyQt5 import QtWidgets
from PyQt5.QtGui import QMovie
from PyQt5.QtCore import QSize
from threading import Thread
class Main_Window(QMainWindow):
def __init__(self):
QMainWindow.__init__(self)
self.setMinimumSize(QSize(500, 500))
self.setWindowTitle("Main Window")
centralWidget = QWidget(self)
self.setCentralWidget(centralWidget)
gridLayout = QGridLayout(self)
centralWidget.setLayout(gridLayout)
gif = QLabel(self)
gif.setGeometry(0,0,500,500)
self.movie = QMovie(r"gif.gif")
gif.setMovie(self.movie)
self.movie.start()
self.show()
Thread(target=self.function_on_thread).start()
def function_on_thread(self):
for i in range(0,1000000):
print(i)
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
MainWin = Main_Window()
sys.exit(app.exec_())
i would like to embed the glb file to pyqt gui with vtk python library. I wrote pieces of code but it does not embed the sketch to the pyqt gui. Everytime there have been placing in the second windows form. Here is the example:
And here is the my source code that i am trying to embed it to gui:
import sys
import vtk
try:
from PyQt5.QtWidgets import QMainWindow, QAction, qApp, QApplication
from PyQt5.QtWidgets import QWidget, QSizePolicy, QPushButton, QVBoxLayout, QFrame
from PyQt5.QtGui import QIcon
from PyQt5.QtCore import Qt, pyqtSignal, QTimer, QObject, QSize, QEvent
except ImportError:
raise ImportError("Cannot load either PyQt5")
from vtk.qt.QVTKRenderWindowInteractor import QVTKRenderWindowInteractor
class Menu(QMainWindow):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
importer = vtk.vtkGLTFImporter()
importer.SetFileName("uydu.glb")
importer.Read()
global vtk_render_window
vtk_renderer = importer.GetRenderer()
vtk_render_window = importer.GetRenderWindow()
self.setGeometry(190, 300, 300, 200)
self.setWindowTitle('Simple menu')
self.show()
self.frame = QFrame()
self.vl = QVBoxLayout()
vtk_render_window_interactor = QVTKRenderWindowInteractor(self.frame)
vtk_render_window_interactor.SetRenderWindow(vtk_render_window)
colors = vtk.vtkNamedColors()
vtk_renderer.SetBackground(colors.GetColor3d('White'))
actor = vtk.vtkActor()
actor.GetProperty().SetDiffuse(0.8)
actor.GetProperty().SetDiffuseColor(colors.GetColor3d('Black'))
actor.GetProperty().SetSpecular(0.3)
actor.GetProperty().SetSpecularPower(60.0)
vtk_render_window.SetSize(600, 600)
vtk_render_window.SetWindowName('3D Visualizer')
vtk_render_window_interactor.Initialize()
# Add callback for getting data from Arduino
#vtk_render_window_interactor.CreateRepeatingTimer(1000)
#vtk_render_window_interactor.AddObserver("TimerEvent", information_callback)
global vtk_actors
vtk_actors = vtk_renderer.GetActors
self.vl.addWidget(vtk_render_window_interactor)
self.renderer = vtk.vtkRenderer()
self.renderer.SetBackground(.3, .4, .5 )
self.renwin = vtk_render_window_interactor.GetRenderWindow()
self.renwin.AddRenderer(self.renderer)
# An interactor
self.inter = self.renwin.GetInteractor()
# add the custom style
self.style = MouseInteractorHighLightActor()
self.style.SetDefaultRenderer(self.renderer)
vtk_render_window_interactor.GetRenderWindow().AddRenderer(self.renderer)
#self.iren = self.vtkWidget.GetRenderWindow().GetInteractor()
self.inter.SetInteractorStyle(self.style)
#self.iren.SetInteractorStyle(self.inter)
#self.iren = self.vtkWidget.GetRenderWindow().SetInteractor(self.inter)
self.renderer.ResetCamera()
self.frame.setLayout(self.vl)
self.setCentralWidget(self.frame)
self.show()
self.inter.Initialize()
self.inter.Start()
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = Menu()
sys.exit(app.exec_())
You have to pass the renderWindow of vtkGLTFImporter as rw parameter to the QVTKRenderWindowInteractor widget:
import sys
import vtk
try:
from PyQt5.QtWidgets import QMainWindow, QApplication
from PyQt5.QtWidgets import QWidget, QVBoxLayout
except ImportError:
raise ImportError("Cannot load either PyQt5")
from vtk.qt.QVTKRenderWindowInteractor import QVTKRenderWindowInteractor
class Menu(QMainWindow):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
self.setGeometry(190, 300, 300, 200)
self.setWindowTitle("Simple menu")
self.container = QWidget()
vl = QVBoxLayout(self.container)
self.setCentralWidget(self.container)
self.resize(640, 480)
importer = vtk.vtkGLTFImporter()
importer.SetFileName("uydu.glb")
importer.Read()
renderer = importer.GetRenderer()
render_window = importer.GetRenderWindow()
vtk_widget = QVTKRenderWindowInteractor(rw=render_window)
vl.addWidget(vtk_widget)
vtk_widget.Initialize()
vtk_widget.Start()
colors = vtk.vtkNamedColors()
renderer.SetBackground(colors.GetColor3d("White"))
renderer.ResetCamera()
if __name__ == "__main__":
app = QApplication(sys.argv)
ex = Menu()
ex.show()
sys.exit(app.exec_())
I have a form with a TableView and a function that handles refreshing buttons for adding and removing data in the table etc.
I want to update the states of actions in contextmenu:
I can with the mouse events (tableWidget.clicked) but not with the KeyPressEvent (Up and Down)
I tried with the table keyPressEvent event, but for some reason the keys no longer work.
How to intercept the up and down keys of the table to update buttons for example.
here after an extract of the code :
import sys
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtCore import Qt, QModelIndex, QVariant, QAbstractItemModel, QEvent
from PyQt5.QtGui import QFont, QKeyEvent
import numpy as np
from modules import *
class MainWindow(QtWidgets.QMainWindow):
def __init__(self):
super().__init__()
self.setObjectName("MainWindow")
self.setMinimumSize(QtCore.QSize(1024, 860))
self.setMaximumSize(QtCore.QSize(2400, 1024))
self.setStyleSheet("background-color: rgb(240, 240, 240);")
self.setToolButtonStyle(QtCore.Qt.ToolButtonIconOnly)
self.centralWidget = QtWidgets.QWidget(self)
self.gridLayout = QtWidgets.QGridLayout(self.centralWidget)
self.setCentralWidget(self.centralWidget)
self.retranslateUi()
self.connectActions()
self.tableWidget.customContextMenuRequested.connect(self.context_menu_Show)
def bpuHadChanged(self, changed=False):
self.bpuChanged = changed
self.actionSave.setEnabled(changed)
def saveFile(self):
# TODO
self.actionSave.setEnabled(False)
def setBPU(self, bpu):
self.bpu = bpu
self.model = TableModel(self.bpu, bpuNewLine)
self.tableWidget.setModel(self.model)
self.tableWidget.resizeColumnToContents(0)
self.updateActionsStates()
def connectActions(self):
self.actionNew.triggered.connect(self.newFile)
self.actionQuit.triggered.connect(self.quit)
self.actionAdd_une_ligne_bordereau.triggered.connect(self.addLine)
self.actionRemoveSelectedLine.triggered.connect(self.RemoveLigne)
self.actionInsertLine.triggered.connect(self.insertLine)
self.actionSave.triggered.connect(self.saveFile)
self.tableWidget.clicked.connect(self.updateActionsStates)
# TODO add connections for up et down actions
def context_menu_Show(self):
self.updateActionsStates()
cursor = QtGui.QCursor()
self.contextMenu.exec_(cursor.pos())
pass
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
window = MainWindow()
window.setBPU(bpu)
window.show()
app.exec_()
This is my first time using Qt Designer, I create function to get datetime data and then store as string in textedit
import sys
from PyQt5.QtWidgets import QMainWindow, QApplication
from PyQt5.QtCore import *
from PyQt5 import uic
Ui_MainWindow, QtBaseClass = uic.loadUiType("datetime2.ui")
class MyApp(QMainWindow):
def __init__(self):
super(MyApp,self).__init__()
self.ui = Ui_MainWindow()
self.ui.setupUi(self)
self.ui.pushButton.clicked.connect(self.GetDatetime)
def GetDatetime(self):
dt = self.ui.dateTimeEdit.dateTime()
dt_string = dt.toString(self.ui.dateTimeEdit.displayFormat())
self.ui.textEdit.setText(dt_string)
if __name__ == "__main__":
if not QApplication.instance():
app = QApplication(sys.argv)
else:
app = QApplication.instance()
window = MyApp()
window.show()
app.exec()
Here the output
When I change dateTimeEdit column and press button the button, the value in edit text also change.
My question is, how to set datetime with local time every open the program ?
And my second question how to show the second's time, because when I ran the program, can't shown second's value ?
You have to have the current time using QDateTime.currentDateTime() and set it in the QDateTimeEdit using the setDateTime() method.
To show the seconds you must set a displayFormat that shows the seconds, for example: dd/MM/yyyy hh:mm:ss.
import sys
from PyQt5 import QtCore, QtWidgets, uic
Ui_MainWindow, QtBaseClass = uic.loadUiType("datetime2.ui")
class MyApp(QtWidgets.QMainWindow):
def __init__(self):
super(MyApp, self).__init__()
self.ui = Ui_MainWindow()
self.ui.setupUi(self)
self.ui.pushButton.clicked.connect(self.GetDatetime)
self.ui.dateTimeEdit.setDateTime(QtCore.QDateTime.currentDateTime())
self.ui.dateTimeEdit.setDisplayFormat("dd/MM/yyyy hh:mm:ss")
def GetDatetime(self):
dt = self.ui.dateTimeEdit.dateTime()
dt_string = dt.toString(self.ui.dateTimeEdit.displayFormat())
self.ui.textEdit.setText(dt_string)
if __name__ == "__main__":
app = QtWidgets.QApplication.instance()
if app is None:
app = QtWidgets.QApplication(sys.argv)
window = MyApp()
window.show()
sys.exit(app.exec())