Disable mouse pointer in QGraphicsView - python-3.x

I want to disable the mouse pointer in a QGraphicsView.
What line of code do I need to add in the following example?
import sys
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import QApplication, QGraphicsView
class GraphicsWindow(QGraphicsView):
def __init__(self, parent=None):
super().__init__(parent)
self.showFullScreen()
def keyPressEvent(self, event):
if event.key() == Qt.Key_Escape:
self.close()
if __name__ == "__main__":
app = QApplication(sys.argv)
graphics_window = GraphicsWindow()
graphics_window.show()
sys.exit(app.exec_())

Qt::BlankCursor A blank/invisible cursor, typically used when the cursor shape needs to be hidden.
import sys
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import QApplication, QGraphicsView
class GraphicsWindow(QGraphicsView):
def __init__(self, parent=None):
super().__init__(parent)
self.showFullScreen()
self.setCursor(Qt.BlankCursor) # < ------
def keyPressEvent(self, event):
if event.key() == Qt.Key_Escape:
self.close()
if __name__ == "__main__":
app = QApplication(sys.argv)
graphics_window = GraphicsWindow()
graphics_window.show()
sys.exit(app.exec_())

Related

PyQt5 does not redrawing widget

Force repainting does not repaint PyQt5 widget (Qlabel, QTextEdit, even QProgressBar and etc)
Tested platforms: Linux, MacOS
PyQt5 version: 5.15.7
Installed from pip
As example I created simple app that updating text in QLabel widget in for loop. Force repainting doesnt working
import sys
from time import sleep
from PyQt5.QtWidgets import (QWidget, QApplication, QPushButton, QLabel)
class Example(QWidget):
def __init__(self):
super().__init__()
self.text = QLabel('Test', self)
self.text.move(10, 10)
self.text.resize(60,20)
self.button = QPushButton('Run', self)
self.button.move(17,40)
self.button.clicked.connect(self.some_activity)
self.setGeometry(300, 300, 100, 80)
self.show()
def some_activity(self):
for i in range(100):
text = f'i = {i}'
self.text.setText(text)
# self.text.update() -> Nothing happens (it shouldnt: https://doc.qt.io/qt-5/qwidget.html#update)
self.text.repaint() # -> Nothing happens
self.repaint() # -> Nothing happens
print(f'Text updated: {text}')
sleep(0.03)
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = Example()
sys.exit(app.exec_())
Video demonstration: link
Just needed to use QThread to use for loop in my program
Thanks #musicamante for helping.
import sys
from time import sleep
from PyQt5 import QtCore
from PyQt5.QtWidgets import (QWidget, QApplication, QPushButton, QLabel)
class Thread(QtCore.QThread):
signal = QtCore.pyqtSignal(str)
def __init__(self, parent=None): QtCore.QThread.__init__(self, parent)
def run(self):
for i in range(100):
text = f'i = {i}'
print(f'Text updated: {text}')
self.signal.emit(text)
sleep(.3)
class Example(QWidget):
def __init__(self):
super().__init__()
self.text = QLabel('Test', self)
self.text.move(10, 10)
self.text.resize(60,20)
self.thread = Thread()
self.thread.signal.connect(self.signal, QtCore.Qt.QueuedConnection)
self.button = QPushButton('Run', self)
self.button.move(17,40)
self.button.clicked.connect(self.thread.start)
self.setGeometry(300, 300, 100, 80)
self.show()
def signal(self, text): self.text.setText(text)
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = Example()
sys.exit(app.exec_())

Issue in Pyqt with next and previous Pages

so I'm currently working on a little project but I have an issue and all what I've tried did not work. I have 2 files :
Page1test :
from PyQt5 import QtWidgets
from PyQt5.QtWidgets import QPushButton, QWidget, QLabel
import sys
from page2test import Page2
class Page1(QWidget):
def __init__(self):
super(Page1, self).__init__()
self.setWindowTitle("Page 1")
label1 = QLabel(self)
label1.setText("\n PAGE 1")
self.btn_inMyApp = QPushButton ('Next page', self)
self.btn_inMyApp.setGeometry(1500,800,275,125)
self.btn_inMyApp.clicked.connect(self.closePage1_OpenPage2)
self.show()
def closePage1_OpenPage2(self):
self.Open = Page2()
self.Open.showMaximized()
self.close()
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
window = Page1()
window.showMaximized()
sys.exit(app.exec_())
And page2test :
from PyQt5.QtWidgets import QPushButton, QWidget, QLabel
from Page1test import Page1
class Page2(QWidget):
def __init__(self):
super(Page2, self).__init__()
self.setWindowTitle("Test window principale")
label1 = QLabel(self)
label1.setText("\n Page2")
self.btn_inMyApp = QPushButton ('previous Page', self)
self.btn_inMyApp.setGeometry(1500,800,275,125)
self.btn_inMyApp.clicked.connect(self.closePage2_OpenPage1)
self.show()
def closePage2_OpenPage1(self):
self.Open = Page1()
self.Open.showMaximized()
self.close()
I run the code of Page1test : empty window with just a Qpushbutton "Next Page", goal : we click on it and it open Page 2 (and close Page 1). And, when we are in Page 2, we have A Qpushbutton with "Previous Page" and when we click on it, it opens page 1, and close Page 2. Like a loop.
But, when I run the code, it returns an error :
cannot import name 'Page2' from partially initialized module 'page2test' (most likely due to a circular import)
and I have no idea how to fix it...
If someone had an idea, it would be really helpful.
So, I've finally found the solution, that was not so difficult in the end. Here it is (if it can help someone) :
Instead of making 2 files, I've done just 1 file. Here is the code :
from PyQt5 import QtWidgets
from PyQt5.QtWidgets import QPushButton, QWidget, QLabel, QMainWindow
import sys
class MyApp(QWidget):
def __init__(self):
super(MyApp, self).__init__()
self.setWindowTitle("Page 1")
label1 = QLabel(self)
label1.setText("\n PAGE 1")
self.btn_inMyApp = QPushButton ('Page suivante', self)
self.btn_inMyApp.setGeometry(1500,800,275,125)
self.btn_inMyApp.clicked.connect(self.closePage1_OpenPage2)
self.show()
def btn1_onClicked(self):
pass
def closePage1_OpenPage2(self):
self.Open = NewApp()
self.Open.showMaximized()
self.close()
class NewApp(QMainWindow):
def __init__(self):
super(NewApp, self).__init__()
self.setWindowTitle("Test window principale")
label1 = QLabel(self)
label1.setText("\n Page2")
self.btn_inMyApp = QPushButton ('previous Page', self)
self.btn_inMyApp.setGeometry(1500,800,275,125)
self.btn_inMyApp.clicked.connect(self.closePage2_OpenPage1)
self.show()
def closePage2_OpenPage1(self):
self.Open = MyApp()
self.Open.showMaximized()
self.close()
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
window = MyApp()
window.showMaximized()
sys.exit(app.exec_())
```

My gui doesn't appear when I use while loop as a startup function in pyqt and python

I want to use startup function which should have while loop.
but I run the code my gui doesn't appear until while loop ends.
I tried with self.show() it can make show gui but it doesn't allow to use sys.exit()
import sys
from PyQt5.QtWidgets import QApplication
from PyQt5 import uic
import time
form_class,QMainWindow=uic.loadUiType('youhua.ui')
class MyWindow(QMainWindow,form_class):
def __init__(self):
super().__init__()
self.setupUi(self)
#self.show()
self.myfunc()
def myfunc(self):
k=1
stat=True
while stat:
k=k+1
time.sleep(1)
self.statusMessage.append(str(k))
QApplication.processEvents()
if k>10:
stat=False
#sys.exit()
if __name__=='__main__':
app=QApplication(sys.argv)
myWindow=MyWindow()
myWindow.show()
app.exec_()
If you need to perform an action again, you have several options.
For example, if each iteration takes very little time, without the possibility of blocking the main loop, you can replace the cycle with a timer (QTimer) and call the method each time, which is responsible for obtaining new data and updating the necessary interface elements in accordance with them:
import sys
from PyQt5 import QtCore, QtWidgets
from PyQt5.QtWidgets import QApplication, QMainWindow
from PyQt5 import uic
from PyQt5.QtCore import QThread, QTimer
import time
#form_class, QMainWindow = uic.loadUiType('youhua.ui')
class MyWindow(QMainWindow): #, form_class):
def __init__(self):
super().__init__()
self.k = 0
centralWidget = QtWidgets.QWidget(self)
self.setCentralWidget(centralWidget)
self.button = QtWidgets.QPushButton('Start', self)
self.button.clicked.connect(self.read_data)
self.label_data = QtWidgets.QLabel(self, alignment=QtCore.Qt.AlignCenter)
self.label_data.setText('Pending')
layout = QtWidgets.QGridLayout(centralWidget)
layout.addWidget(self.label_data)
layout.addWidget(self.button)
self.timer = QtCore.QTimer(self)
self.timer.setInterval(1000)
self.timer.timeout.connect(self.read_data_from_sensor)
#QtCore.pyqtSlot()
def read_data(self):
''' Start / Stop reading at the touch of a button '''
if not self.timer.isActive():
self.timer.start()
self.button.setText("Stop")
else:
self.timer.stop()
self.button.setText("Start")
self.label_data.setText("Pending")
#QtCore.pyqtSlot()
def read_data_from_sensor(self):
dt = time.strftime("%Y-%m-%d %H:%M:%S")
self.label_data.setText(dt)
self.label_data.adjustSize()
self.k += 1
self.statusBar().showMessage('{} item(s)'.format(self.k))
if self.k > 10:
self.timer.stop()
self.button.setText("Start")
self.label_data.setText("Pending")
self.k = 0
if __name__=='__main__':
app = QApplication(sys.argv)
myWindow = MyWindow()
myWindow.show()
app.exec_()
What you wrote may also work, but this is not very good. You can compare.
import sys
from PyQt5.QtWidgets import QApplication, QMainWindow
from PyQt5 import uic
from PyQt5.QtCore import QThread
#import time
#form_class, QMainWindow = uic.loadUiType('youhua.ui')
class MyWindow(QMainWindow): #, form_class):
def __init__(self):
super().__init__()
# self.setupUi(self)
self.show()
self.myfunc()
def myfunc(self):
k = 0
stat = True
while stat:
k += 1
# time.sleep(1)
# self.statusMessage.append(str(k))
self.statusBar().showMessage('{} item(s)'.format(k))
QThread.msleep(1000)
QApplication.processEvents()
if k>10:
stat=False
#sys.exit()
if __name__=='__main__':
app = QApplication(sys.argv)
myWindow = MyWindow()
# myWindow.show()
app.exec_()
In your loop you are sleeping for 10 second, since you are creating a while loop on the main thread, the GUI wont show until the loop is done because it would be blocking the main thread. You can test this by removing time.sleep(1).
Without changing your code much, try this:
import sys,threading, time
from PyQt5.QtWidgets import QApplication
from PyQt5 import uic
form_class,QMainWindow=uic.loadUiType('youhua.ui')
class MyWindow(QMainWindow,form_class):
def __init__(self):
super().__init__()
self.setupUi(self)
#self.show()
t = threading.Thread(target=self.myfunc)
t.start()
def myfunc(self):
k=1
stat=True
while stat:
k=k+1
time.sleep(1)
self.statusMessage.append(str(k))
QApplication.processEvents()
if k>10:
stat=False
#sys.exit() - if you are trying to close the window here use self.close()
if __name__=='__main__':
app=QApplication(sys.argv)
myWindow=MyWindow()
myWindow.show()
sys.exit(app.exec_())

How to make "finish" button in QStackedWidget

I trying to create "Finish" button in QStackedWidget.
In a "checkButtons" function i checking current page index and set click events and text. I tried to check it by class name, but it doesn't work too.
Here is a code:
import sys
from PyQt5.QtGui import QIcon
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import (QApplication, QDialog, QComboBox, QStackedWidget, QWidget,
QPushButton, QLabel, QVBoxLayout, QHBoxLayout, QStyle)
class Main(QDialog):
def __init__(self, parent=None):
super(Main, self).__init__(parent)
# Main window setup
self.setWindowTitle("Stacked widget example")
self.setWindowIcon(self.style().standardIcon(QStyle.SP_FileDialogNewFolder))
self.setMinimumSize(400, 400)
self.setMaximumSize(640, 480)
self.rootVBox = QVBoxLayout()
self.rootHBox = QHBoxLayout()
self.rootHBox.addStretch()
self.rootVBox.addStretch()
self.pages = [FirstPage, SecondPage]
self.stacked = QStackedWidget(self)
for i in self.pages: self.stacked.addWidget(i(self))
self.pageState = True
self.buttonNext = QPushButton("Next")
self.buttonNext.clicked.connect(self.buttonNextConnect)
self.buttonBack = QPushButton("Back")
self.buttonBack.clicked.connect(self.buttonBackConnect)
self.rootHBox.addWidget(self.buttonBack)
self.rootHBox.addWidget(self.buttonNext)
self.rootVBox.addLayout(self.rootHBox)
self.setLayout(self.rootVBox)
def checkButtons(self):
print(self.stacked.currentIndex())
# I tried to check self.stacked.currentIndex() but it didn't work too
# if self.stacked.currentWidget().__class__ == self.pages[-1]:
if self.stacked.currentIndex() == len(self.pages) - 1:
self.buttonNext.setText("Finish")
self.buttonNext.clicked.connect(self.close)
elif self.stacked.currentIndex() < len(self.pages) - 1:
self.buttonNext.setText("Next")
self.buttonNext.clicked.connect(self.buttonNextConnect)
def buttonNextConnect(self):
self.stacked.setCurrentIndex(self.stacked.currentIndex() + 1)
self.checkButtons()
def buttonBackConnect(self):
self.stacked.setCurrentIndex(self.stacked.currentIndex() - 1)
self.checkButtons()
def finish(self):
self.close()
class FirstPage(QWidget):
def __init__(self, parent=None):
super(FirstPage, self).__init__(parent)
label = QLabel("First page")
rootVBox = QVBoxLayout()
rootHBox = QHBoxLayout()
rootHBox.addWidget(label)
rootVBox.addLayout(rootHBox)
self.setLayout(rootVBox)
class SecondPage(QWidget):
def __init__(self, parent=None):
super(SecondPage, self).__init__(parent)
label = QLabel("Second page")
rootVBox = QVBoxLayout()
rootHBox = QHBoxLayout()
rootHBox.addWidget(label)
rootVBox.addLayout(rootHBox)
self.setLayout(rootVBox)
if __name__ == '__main__':
app = QApplication(sys.argv)
main = Main()
main.show()
sys.exit(app.exec_())
If you try to press "next", "back" and then "next" again a program will be close. So, how can i fix it? Should i just make control buttons for each widget?
You must use the currentChanged signal of the QStackedWidget to know what page you are on and thus change the text, but in the buttonNextConnect slot you should check if you are already on the last page before switching to a new page, if you are then call to finish and if you do not change to another page
class Main(QDialog):
def __init__(self, parent=None):
super(Main, self).__init__(parent)
# Main window setup
self.setWindowTitle("Stacked widget example")
self.setWindowIcon(self.style().standardIcon(QStyle.SP_FileDialogNewFolder))
self.setMinimumSize(400, 400)
self.setMaximumSize(640, 480)
rootVBox = QVBoxLayout(self)
rootHBox = QHBoxLayout()
rootHBox.addStretch()
rootVBox.addStretch()
self.pages = [FirstPage, SecondPage]
self.stacked = QStackedWidget(self)
for i in self.pages: self.stacked.addWidget(i(self))
self.buttonNext = QPushButton("Next")
self.buttonNext.clicked.connect(self.buttonNextConnect)
self.buttonBack = QPushButton("Back")
self.buttonBack.clicked.connect(self.buttonBackConnect)
rootHBox.addWidget(self.buttonBack)
rootHBox.addWidget(self.buttonNext)
rootVBox.addLayout(rootHBox)
self.stacked.currentChanged.connect(self.on_currentChanged)
def buttonNextConnect(self):
if self.stacked.currentIndex() == self.stacked.count() -1:
self.finish()
if self.stacked.currentIndex() < self.stacked.count() -1:
self.stacked.setCurrentIndex(self.stacked.currentIndex() + 1)
def buttonBackConnect(self):
if self.stacked.currentIndex() > 0:
self.stacked.setCurrentIndex(self.stacked.currentIndex() - 1)
def on_currentChanged(self, index):
if index == self.stacked.count() -1:
self.buttonNext.setText("Finish")
else:
self.buttonNext.setText("Next")
def finish(self):
self.close()
Another option is to use QWizard and QWizardPage:
import sys
from PyQt5 import QtCore, QtGui, QtWidgets
class Main(QtWidgets.QWizard):
def __init__(self, parent=None):
super(Main, self).__init__(parent)
buttons = [
QtWidgets.QWizard.Stretch,
QtWidgets.QWizard.BackButton,
QtWidgets.QWizard.NextButton,
QtWidgets.QWizard.FinishButton
]
self.setButtonLayout(buttons)
self.addPage(FirstPage())
self.addPage(SecondPage())
class FirstPage(QtWidgets.QWizardPage):
def __init__(self, parent=None):
super(FirstPage, self).__init__(parent)
self.setTitle("First page")
class SecondPage(QtWidgets.QWizardPage):
def __init__(self, parent=None):
super(SecondPage, self).__init__(parent)
self.setTitle("Second page")
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
main = Main()
main.show()
sys.exit(app.exec_())

PyQT how to make a QEvent.Enter on QPushbutton?

My main goal really is,i have a Qpushbutton and a frame, what im trying to do is. when i hover on a Qpushbutton the frame will show up. using visible false. can somebody help me please on how to make an events?
Here's a quick example, similar to the example I gave in your previous question:
from PyQt4.QtGui import QApplication, QMainWindow, QPushButton, \
QWidget, QLabel
from PyQt4.QtCore import pyqtSignal
class HoverButton(QPushButton):
mouseHover = pyqtSignal(bool)
def __init__(self, parent=None):
QPushButton.__init__(self, parent)
self.setMouseTracking(True)
def enterEvent(self, event):
self.mouseHover.emit(True)
def leaveEvent(self, event):
self.mouseHover.emit(False)
class MainWindow(QMainWindow):
def __init__(self, parent=None):
QMainWindow.__init__(self, parent)
self.button = HoverButton(self)
self.button.setText('Button')
self.label = QLabel('QLabel uses QFrame...', self)
self.label.move(40, 40)
self.label.setVisible(False)
self.button.mouseHover.connect(self.label.setVisible)
def startmain():
app = QApplication(sys.argv)
mainwindow = MainWindow()
mainwindow.show()
sys.exit(app.exec_())
if __name__ == "__main__":
import sys
startmain()

Resources