PyQt4 Label not showing - python

I am very new to PyQt4 and this question is probably very simple but I have tried many different things and nothing works. I am trying to make a label in PyQt4.
import sys
from PyQt4 import QtCore
from PyQt4 import QtGui
class Display(QtGui.QWidget):
def __init__(self):
super(Display, self).__init__()
self.time = Time() #Another class in the program
self.ShowFullScreen()
self.setStyleSheet("background-color: black;")
self.show()
self.MainDisplay()
def MainDisplay(self):
self.timedisplay = QtGui.QLabel(self)
self.timedisplay.setStyleSheet("font: 30pt Helvetica; color: white;")
self.timedisplay.setText(time.GetTime())
self.show()
if __name__ == "__main__":
app = QtGui.QApplication(sys.argv)
GUI = Display()
sys.exit(app.exec())
The label doesn't show up, and there is no error message. What am I doing wrong?

I use PySide and not Qt, but they are supposed to be 99.99% compatible. The main problem is your call to the show() function, which makes the window visible. You have two calls to show. The first time it is called, you have not yet called MainDisplay so the QLabel hasn't been created yet. The second time you call show the window is already visible, so nothing changes.
If you create the widgets first and call show once, at the end, it will work the way you want. With this code the label shows up.
There are other issues:
You will have to change the import statements back the way you had them.
I did not have your Time class, so I just wrote a simple piece of text into the label.
The function ShowFullScreen should be showFullScreen.
The function that runs the event loop in QtApp is named exec_ not exec.
import sys
from PySide import QtCore
from PySide import QtGui
class Display(QtGui.QWidget):
def __init__(self):
super(Display, self).__init__()
self.setStyleSheet("background-color: black;")
self.MainDisplay()
self.showFullScreen()
def MainDisplay(self):
self.timedisplay = QtGui.QLabel(self)
self.timedisplay.setStyleSheet("font: 30pt Helvetica; color: white;")
self.timedisplay.setText("What time is it now?")
if __name__ == "__main__":
app = QtGui.QApplication(sys.argv)
GUI = Display()
sys.exit(app.exec_())

Related

Printing some text in a Label, depending on textbox input - PyQT5

I need help figuring out how to use the value written in a textbox in PyQT5, and use that value to build an IF statement. Any suggestions on how to do it? I have tried to declare the text in the textbox as a variable and use it in the IF statement but I can't seem to figure it out how to do it properly, and every time i run the code, some exit code shows (-1073741819 (0xC0000005) ).
Summing up, can't use pass the value of the textbox to the variable in order to do an IF statement.
I had this code down below:
from PyQt5 import QtWidgets
from PyQt5.QtWidgets import QApplication, QMainWindow, QPushButton, QTextEdit
def window():
app = QApplication(sys.argv)
win = QMainWindow()
win.setGeometry(200, 200, 400, 400)
win.setWindowTitle("Register Program")
label = QtWidgets.QLabel(win)
label.setText("Random Text")
label.move(169, 15)
label2 = QtWidgets.QLabel(win)
label2.resize(300, 100)
label2.setText("1- Register new person\n2- See all regestries\n3- See last regestry\n\nPress ESC to exit\n")
label2.move(70, 50)
textbox = QtWidgets.QLineEdit(win)
textbox.setText("")
textbox.resize(250, 25)
textbox.move(70, 250)
button1 = QtWidgets.QPushButton(win)
button1.move(150, 300)
button1.setText("Submit")
button1.clicked.connect(clicked)
button2 = QtWidgets.QPushButton(win)
button2.move(150, 335)
button2.setText("Close")
button2.clicked.connect(close)
win.show()
sys.exit(app.exec_())
def clicked():
inpt = int(window().textbox.text)
if inpt == 1:
print("Hello")
def close():
sys.exit()
window()```
If you're just looking to get user input, there's a builtin static method you can call for requesting input of a particular type: https://doc.qt.io/qt-5/qinputdialog.html#getText
If you want to make your own widget however, you need to use the signals and slots to trigger a python method to store the value. This is easiest to do in a class. You can trigger the method whenever the text changes with the textChanged signal and do whatever you need to do with it.
(Note, I haven't run this as I don't have PyQt5 currently installed, but it should work)
from PyQt5 import QtCore, QtGui, QtWidgets
class Widget(QtWidgets.QWidget):
def __init__(self, parent=None):
# type: (QtWidgets.QWidget) -> None
super(Widget, self).__init__(parent)
self.line_edit = QtWidgets.QLineEdit()
main_layout = QtWidgets.QVBoxLayout()
main_layout.addWidget(self.line_edit)
self.setLayout(main_layout)
self.line_edit.textChanged.connect(self.on_text_changed)
def get_text(self):
return self.line_edit.text()
def on_text_changed(self, text):
print("The text was changed to:", text)
if __name__ == '__main__':
app = QtWidgets.QApplication([])
widget = Widget()
widget.show()
app.exec_()
Edit: Also, to clarify why you're getting an error, QApplication is a singleton. This means there can only ever be one created. If you try to create a second, you'll get an error. The best way to access the current QApplication is to call QApplication.instance(). You also only call app.exec_() once, as once the application is running it will continue to run in the background. You should use signal/slots to interact with the UI and trigger the code you want to run.

PyQt - QPushButton loop

I'm new to Python and PyQt so sorry if I can't describe my problems clearly. I want to do a cinema seat selector UI and this is the code I have made below:
import sys
from PyQt5 import uic
from PyQt5.QtWidgets import (QWidget, QApplication)
class Ui2(QWidget):
def __init__(self):
super(Ui2, self).__init__()
uic.loadUi('seat.ui', self)
self.A1.setStyleSheet("background-color: red")
self.B1.clicked.connect(self.greenButton)
self.show()
def greenButton(self):
self.B1.setStyleSheet("background-color: green")
self.B1.clicked.connect(self.whiteButton)
def whiteButton(self):
self.B1.setStyleSheet("background-color: white")
self.B1.clicked.connect(self.greenButton)
if __name__ == '__main__':
app = QApplication(sys.argv)
window = Ui2()
sys.exit(app.exec_())
The problem is, if I click the button B1 multiple times the program will freeze - I read it somewhere that this is caused by full memory.
Also this is only for the button B1, what should I do if I want to implement the same functions for all buttons?
Thanks a lot!
You shouldn't call self.B1.clicked.connect so many times. Each time you call that function, it registers another event handler. When the button is clicked, all the event handlers that have ever been registered get called. So as you keep clicking, each click causes more and more things to happen. Eventually it fails.
In general you want to try to have one handler for each event. Here is one simple way to do that:
import sys
from PyQt5 import uic
from PyQt5.QtWidgets import (QWidget, QApplication)
class Ui2(QWidget):
def __init__(self):
super(Ui2, self).__init__()
uic.loadUi('seat.ui', self)
self.b1_color = "green"
self.A1.setStyleSheet("background-color: red")
self.B1.clicked.connect(self.onButton)
self.show()
def onButton(self):
if self.b1_color == "green":
self.b1_color = "white"
else:
self.b1_color = "green"
self.B1.setStyleSheet("background-color: " + self.b1_color)
Tested with PySide and Qt4.8, but it should still work in your environment (I hope).

show Qwidget window without MainWindow

I am having problems showing a QWidget window for the user to input some data.
My script has not GUI, but I just want to show this small QWidget window.
I created the window with QtDesigner, and now I am trying to show the QWidget window like this:
from PyQt4 import QtGui
from input_data_window import Ui_Form
class childInputData(QtGui.QWidget ):
def __init__(self, parent=None):
super(childInputData, self).__init__()
self.ui = Ui_Form()
self.ui.setupUi(self)
self.setFocus(True)
self.show()
And then, from my main class, I am doing like that:
class myMainClass():
childWindow = childInputData()
That gave me the error:
QWidget: Must construct a QApplication before a QPaintDevice
So now I am doing, from my main class:
class myMainClass():
app = QtGui.QApplication(sys.argv)
childWindow = childInputData()
Now there is no error, but the window is showed twice and the script does not wait until the data is entered, it just shows the window and continues without waiting.
What is wrong here?
It's perfectly normal that the window is shown and the script goes on: you never told the script to wait for the user to answer. You just told it to show a window.
What you would like is the script to stop until the user is done and the window is closed.
Here's one way to do it:
from PyQt4 import QtGui,QtCore
import sys
class childInputData(QtGui.QWidget):
def __init__(self, parent=None):
super(childInputData, self).__init__()
self.show()
class mainClass():
def __init__(self):
app=QtGui.QApplication(sys.argv)
win=childInputData()
print("this will print even if the window is not closed")
app.exec_()
print("this will be print after the window is closed")
if __name__ == "__main__":
m=mainClass()
The exec() method "Enters the main event loop and waits until exit() is called" (doc):
the script will be blocked on the line app.exec_() until the window is closed.
NB: using sys.exit(app.exec_()) would cause the script to end when the window is closed.
An other way is to use QDialog instead of QWidget. You then replace self.show() by self.exec(), which will block the script
From the doc:
int QDialog::exec()
Shows the dialog as a modal dialog, blocking until the user closes it
Finally, this answer of a related question advocates not to use exec, but to set the window modality with win.setWindowModality(QtCore.Qt.ApplicationModal). However this doesn't work here: it blocks inputs in other windows, but do not block the script.
you dont need the myMainClass...do something like this:
import sys
from PyQt4 import QtGui
from input_data_window import Ui_Form
class childInputData(QtGui.QWidget):
def __init__(self, parent=None):
super(childInputData, self).__init__(parent)
self.ui = Ui_Form()
self.ui.setupUi(self)
self.setFocus(True)
if __name__ == "__main__":
app = QtGui.QApplication(sys.argv)
win = childInputData()
win.show()
sys.exit(app.exec_())

How to make a window that occupies the full screen without maximising?

I'm writing in python using Qt
I want to create the application window (with decorations) to occupy the full screen size. Currently this is the code I have:
avGeom = QtGui.QDesktopWidget().availableGeometry()
self.setGeometry(avGeom)
the problem is that it ignores window decorations so the frame is larger... I googled and what not, found this:
http://harmattan-dev.nokia.com/docs/library/html/qt4/application-windows.html#window-geometry
which seems to indicate I need to set the frameGeometry to the avGeom however I haven't found a way to do that. Also, in the comments in the above link it says what I'm after may not be even possible as the programme can't set the frameGeometry before running... If that is the case I just want confirmation that my problem is not solvable.
EDIT:
So I played around with the code a bit and this gives what I want... however the number 24 is basically through trial and error until the window title is visible.... I want some better way to do this... which is window manager independent..
avGeom = QtGui.QDesktopWidget().availableGeometry()
avGeom.setTop(24)
self.setGeometry(avGeom)
Now I can do what I want but purely out of trial and error
Running Ubuntu, using Spyder as an IDE
thanks
Use QtGui.QApplication().desktop().availableGeometry() for the size of the window:
#!/usr/bin/env python
#-*- coding:utf-8 -*-
from PyQt4 import QtGui, QtCore
class MyWindow(QtGui.QWidget):
def __init__(self, parent=None):
super(MyWindow, self).__init__(parent)
self.pushButtonClose = QtGui.QPushButton(self)
self.pushButtonClose.setText("Close")
self.pushButtonClose.clicked.connect(self.on_pushButtonClose_clicked)
self.layoutVertical = QtGui.QVBoxLayout(self)
self.layoutVertical.addWidget(self.pushButtonClose)
titleBarHeight = self.style().pixelMetric(
QtGui.QStyle.PM_TitleBarHeight,
QtGui.QStyleOptionTitleBar(),
self
)
geometry = app.desktop().availableGeometry()
geometry.setHeight(geometry.height() - (titleBarHeight*2))
self.setGeometry(geometry)
#QtCore.pyqtSlot()
def on_pushButtonClose_clicked(self):
QtGui.QApplication.instance().quit()
if __name__ == "__main__":
import sys
app = QtGui.QApplication(sys.argv)
app.setApplicationName('MyWindow')
main = MyWindow()
main.show()
sys.exit(app.exec_())
I've always found inheritting from the QMainWindow class to be particularly useful. Like this:
import sys
from PySide.QtGui import *
from PySide.QtCore import *
class Some_APP(QMainWindow):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
### this line here is what you'd be looking for
self.setWindowState(Qt.WindowMaximized)
###
self.show()
def main():
app = QApplication(sys.argv)
some_app = Some_APP()
sys.exit(app.exec_())
if __name__ == "__main__":
main()

Hover issue in PyQt

I want to do hover. I saw an example and then write a script which will be use as I made program. I am facing one problem that hover only occur if you put mouse on the left corner of button. I want that it will happen for all the button that if i move cursor on button then it should change.
Here is my code:
from PyQt4 import QtGui, QtCore
from PyQt4.QtCore import pyqtSignal
import os,sys
class HoverButton(QtGui.QToolButton):
def enterEvent(self,event):
print("Enter")
button.setStyleSheet("background-color:#45b545;")
def leaveEvent(self,event):
button.setStyleSheet("background-color:yellow;")
print("Leave")
app = QtGui.QApplication(sys.argv)
widget = QtGui.QWidget()
button = QtGui.QToolButton(widget)
button.setMouseTracking(True)
buttonss = HoverButton(button)
button.setIconSize(QtCore.QSize(200,200))
widget.show()
sys.exit(app.exec_())
Is this what you're looking for
from PyQt4 import QtGui, QtCore
from PyQt4.QtCore import pyqtSignal
import os,sys
class Main(QtGui.QWidget):
def __init__(self, parent=None):
super(Main, self).__init__(parent)
layout = QtGui.QVBoxLayout(self) # layout of main widget
button = HoverButton(self)
button.setIconSize(QtCore.QSize(200,200))
layout.addWidget(button) # set your button to the widgets layout
# this will size the button nicely
class HoverButton(QtGui.QToolButton):
def __init__(self, parent=None):
super(HoverButton, self).__init__(parent)
self.setMouseTracking(True)
def enterEvent(self,event):
print("Enter")
self.setStyleSheet("background-color:#45b545;")
def leaveEvent(self,event):
self.setStyleSheet("background-color:yellow;")
print("Leave")
app = QtGui.QApplication(sys.argv)
main = Main()
main.show()
sys.exit(app.exec_())
In your code you had a button in a button and the nested button wasn't assigned to a QLayout widget. Although, I'm not sure why you're adding a button inside of a button. One thing that I've learned from working with GUI's is that it's so much easier if you modularize your code. Now you can take this custom button and apply it somewhere else.
You should use the stylesheet as
QToolButton:hover
{
background-color: rgb(175,175,175);
}
You probably want focus and blur, rather than enter and leave will only fire when the mouse actually enters or leaves the boundary of the button and will probably just be short duration impulses rather than toggles. focus and blur will toggle with the hover.

Categories