I have already read some answers but they do not work for me.
This is my code:
from PyQt5.QtWidgets import QWidget, QCheckBox, QApplication, QHBoxLayout, QLabel
from PyQt5.QtCore import Qt
from PyQt5.QtGui import QPixmap
import sys
class Example(QWidget):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
cbAll = QCheckBox('Slice 1', self) # Slice 1
cbAll.move(1200, 130)
cbAll.toggle()
cbAll.stateChanged.connect(self.OpenSlice1)
self.setGeometry(0, 25, 1365, 700)
self.setWindowTitle('Original Slices')
self.show()
def OpenSlice1(self,state):
pixmap = QPixmap("E:\BEATSON_PROJECT\python\GUI\home.png")
self.lbl = QLabel(self) #Qlabel used to display QPixmap
self.lbl.setPixmap(pixmap)
if state == Qt.Checked:
self.lbl.show()
else:
self.lbl.hide()
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = Example()
sys.exit(app.exec_())
However when it goes into the unchecked option it does not hide the image:
Original window:
Checked Slice 1 window:
From this point on it always shows the image and I want it to hide it. i.e unckecking the box does not work:
The problem is caused because each time you press you are creating a new QLabel and you assign the same variable so you lose access to that element, and then you are closing the new QLabel, but not the old one. What you must do is create it and only hide it for it you could use the setVisible() or hide() and show() method.
class Example(QWidget):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
cbAll = QCheckBox('Slice 1', self) # Slice 1
cbAll.move(1200, 130)
cbAll.toggle()
cbAll.stateChanged.connect(self.OpenSlice1)
pixmap = QPixmap("E:\BEATSON_PROJECT\python\GUI\home.png")
self.lbl = QLabel(self) #Qlabel used to display QPixmap
self.lbl.setPixmap(pixmap)
self.setGeometry(0, 25, 1365, 700)
self.setWindowTitle('Original Slices')
self.show()
def OpenSlice1(self, state):
self.lbl.setVisible(state != Qt.Unchecked)
# or
"""if state == Qt.Checked:
self.lbl.show()
else:
self.lbl.hide()"""
Related
This question already has an answer here:
Get cells of QCalendarWidget
(1 answer)
Closed 7 months ago.
I am trying to get QCalendarWidget's Cell position.
from the upper image, it's cell position must be tuple: (2,4)
I would also appreciate if I can get the cell date and find it's position on another library.
import sys
from PyQt5.QtWidgets import QApplication, QWidget, QLabel, QVBoxLayout, QCalendarWidget
from PyQt5.QtCore import QDate
class MyApp(QWidget):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
cal = QCalendarWidget(self)
cal.setGridVisible(True)
cal.clicked[QDate].connect(self.showDate)
self.lbl = QLabel(self)
date = cal.selectedDate()
self.lbl.setText(date.toString())
vbox = QVBoxLayout()
vbox.addWidget(cal)
vbox.addWidget(self.lbl)
self.setLayout(vbox)
self.setWindowTitle('QCalendarWidget')
self.setGeometry(300, 300, 400, 300)
self.show()
def showDate(self, date):
self.lbl.setText(date.toString())
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = MyApp()
sys.exit(app.exec_())
UPDATE
Ok, I'm sorry, my code didn't meet your demand.
Here you are.
import sys
from PyQt6.QtWidgets import QApplication, QWidget, QLabel, QVBoxLayout, QCalendarWidget, QTableView
from PyQt6.QtCore import QDate, Qt, QModelIndex
class MyApp(QWidget):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
self.cal = QCalendarWidget(self)
self.cal.setGridVisible(True)
self.cal.clicked[QDate].connect(self.showDate)
self.lbl = QLabel(self)
date = self.cal.selectedDate()
self.lbl.setText(date.toString())
vbox = QVBoxLayout()
vbox.addWidget(self.cal)
vbox.addWidget(self.lbl)
self.setLayout(vbox)
self.setWindowTitle('QCalendarWidget')
self.setGeometry(300, 300, 400, 300)
self.show()
def showDate(self, date):
self.lbl.setText(date.toString())
child = self.findChild(QTableView)
c = child.currentIndex()
data = child.model().data(c)
print(c.column() , c.row())
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = MyApp()
sys.exit(app.exec())
Explanation
QCalendarWidget is made from some widgets containing QTableView.
So we get the QTableView by findChild method.
If you click the tile of QTableView, the index is fixed.
The index has row, column.
this solution is a little dirty, but better.
I delete my previous answer.
I have an application where I draw 2 custom widgets and then draw a line between them. I want to add a mousePressEvent to the line.
What would be the best way to do this?
I suppose I could create a QWidget of x pixel thickness and y length and then fill in the whole widget with the colour I want the line to have. Then the QWidget has the mousePressEvent that I can override. This doesn't seem like the most elegant solution and feels more like a workaround. Is there a better way?
import sys
from PyQt5.QtCore import Qt
from PyQt5.QtGui import QPaintEvent, QPainter, QPen, QFont
from PyQt5.QtWidgets import QApplication, QMainWindow, QWidget, QLabel
class MyWidget(QWidget):
def __init__(self, name, parent):
super().__init__(parent)
self.setAutoFillBackground(True)
self.setFixedSize(300, 100)
p = self.palette()
p.setColor(self.backgroundRole(), Qt.white)
self.setPalette(p)
lbl_name = QLabel(name, self)
lbl_name.setFont(QFont('Arial', 16))
lbl_name.move((self.width() - lbl_name.width()) / 2, self.height()/2 - lbl_name.height()/2)
class MainWindow(QMainWindow):
def __init__(self, parent=None):
super().__init__(parent)
self.main_widget = QWidget(self)
self.widget_1 = MyWidget("Widget 1", self)
self.widget_1.move(50, 50)
self.widget_2 = MyWidget("Widget 2", self)
self.widget_2.move(700, 600)
self.resize(1200, 800)
self.setCentralWidget(self.main_widget)
def paintEvent(self, a0: QPaintEvent) -> None:
super().paintEvent(a0)
painter = QPainter(self)
painter.setPen(QPen(Qt.red, 3, Qt.SolidLine))
widget_1_x = self.widget_1.pos().x() + self.widget_1.size().width()
widget_1_y = self.widget_1.pos().y() + self.widget_1.size().height() / 2
widget_2_x = self.widget_2.pos().x()
widget_2_y = self.widget_2.pos().y() + self.widget_2.size().height() / 2
halfway_x = widget_1_x + (widget_2_x - widget_1_x) / 2
# add mousePressEvents to these lines:
painter.drawLine(widget_1_x, widget_1_y, halfway_x, widget_1_y)
painter.drawLine(halfway_x, widget_1_y, halfway_x, widget_2_y)
painter.drawLine(halfway_x, widget_2_y, widget_2_x, widget_2_y)
if __name__ == "__main__":
app = QApplication(sys.argv)
myapp = MainWindow()
myapp.show()
sys.exit(app.exec_())
How the above code looks like when run
from PyQt5.QtWidgets import QApplication, QLabel, QWidget, QFileDialog, QPushButton, QLineEdit,QVBoxLayout, QHBoxLayout
from PyQt5.QtCore import *
from PyQt5.QtGui import QPixmap
from PyQt5.QtWidgets import QApplication, QWidget, QPushButton, QDialog, QVBoxLayout
import Updated_encrypt
import sys
class Window(QWidget):
def __init__(self):
super().__init__()
self.title = 'Encrypt/Decrypt'
self.top = 200
self.left = 500
self.width = 400
self.height = 300
self.InitWindow()
def InitWindow(self):
self.setWindowTitle(self.title)
self.setGeometry(self.left, self.top, self.width, self.height)
vbox = QVBoxLayout()
self.button1 = QPushButton('Encrypt')
self.button1.clicked.connect(self.openSecondDialog)
self.button2 = QPushButton('Decrypt')
vbox.addWidget(self.button1)
vbox.addWidget(self.button2)
self.setLayout(vbox)
self.show()
def openSecondDialog(self):
hbox = QVBoxLayout()
mydialog = QDialog(self)
mydialog.show()
self.button2 = QPushButton('Check Image')
self.button2.clicked.connect(self.getImage)
hbox.addWidget(self.button2)
self.setLayout(hbox)
self.show()
def getImage(self):
hbox = QHBoxLayout()
file_Name = QFileDialog.getOpenFileName(self,
'OpenFile',
'',
'')
image_path = file_Name[0]
updatedImage = Updated_encrypt.decrypt(image_path, 123)
pixmap = QPixmap(updatedImage)
self.label.setPixmap(QPixmap(pixmap))
self.resize(pixmap.width(), pixmap.height())
App = QApplication(sys.argv)
window = Window()
sys.exit(App.exec())
I have my code set up to implement an algorithm to modify an image when my I select it from my pop up dialogue. What I am trying to accomplish is for the image to pop up in a separate window when I click the encrypt button. I can't seem to get anything to pop up in the separate window aside from the window itself. Any help would be appreciated.
You have at least the following errors:
The "hbox" created is being added to the window and not to the QDialog: self.setLayout(hbox), it must be mydialog.setLayout(hbox).
Do not use the same name for 2 different objects as they can cause problems, in your case there are 2 QPushButton assigned to the variable "self.button2".
You try to use the variable "self.label" but never believe it.
Considering the above we can make the following improvements:
Use more descriptive names to easily distinguish their function.
If you are going to have a window that has a different objective, it is better to create a class.
The above avoid the indicated problems, considering the above the solution is:
import sys
from PyQt5.QtGui import QPixmap
from PyQt5.QtWidgets import (
QApplication,
QDialog,
QFileDialog,
QHBoxLayout,
QLabel,
QPushButton,
QVBoxLayout,
QWidget,
)
import Updated_encrypt
class Dialog(QDialog):
def __init__(self, parent=None):
super().__init__(parent)
self.load_image_btn = QPushButton("Check Image")
self.load_image_btn.clicked.connect(self.load_image)
self.image_lbl = QLabel()
lay = QVBoxLayout(self)
lay.addWidget(self.load_image_btn)
lay.addWidget(self.image_lbl)
def load_image(self):
image_path, _ = QFileDialog.getOpenFileName(self, "OpenFile", "", "")
if image_path:
updatedImage = Updated_encrypt.decrypt(image_path, 123)
pixmap = QPixmap(updatedImage)
self.image_lbl.setPixmap(QPixmap(pixmap))
class Window(QWidget):
def __init__(self, parent=None):
super().__init__(parent)
self.title = "Encrypt/Decrypt"
self.InitWindow()
def InitWindow(self):
self.setWindowTitle(self.title)
self.setGeometry(200, 500, 400, 300)
self.encrypt_btn = QPushButton("Encrypt")
self.encrypt_btn.clicked.connect(self.openSecondDialog)
self.decrypt_btn = QPushButton("Decrypt")
vbox = QVBoxLayout(self)
vbox.addWidget(self.encrypt_btn)
vbox.addWidget(self.decrypt_btn)
def openSecondDialog(self):
dialog = Dialog(self)
dialog.show()
if __name__ == "__main__":
app = QApplication(sys.argv)
window = Window()
window.show()
sys.exit(app.exec())
I am trying to create a pop-up window that gets popped-up from pressing on a QPushButton. However, I have a separate QPushButton class that I would like to use. I can't seem to get it working. Anything I am doing wrong?
#import ... statements
import sys
# from ... import ... statements
from PyQt5.QtWidgets import (QMainWindow, QApplication, QPushButton, QGridLayout, QWidget, QHBoxLayout, QLabel,
QVBoxLayout)
from PyQt5.QtCore import Qt
from PyQt5.QtGui import QFont, QFontDatabase, QColor, QPalette, QMovie
from skimage import transform, io
# Create main window of the widget
class MainWindow(QWidget):
def __init__(self):
super().__init__()
#Set a title inside the widget
self.titleLabel = QLabel()
titleText = "some title text"
self.titleLabel.setText(titleText)
# Give the label some flair
self.titleLabel.setFixedWidth(1000)
self.titleLabel.setAlignment(Qt.AlignCenter)
QFontDatabase.addApplicationFont(link_to_custom_font)
font = QFont()
font.setFamily("custom_font_name")
font.setPixelSize(50)
self.titleLabel.setFont(font)
# Set first button - The "Yes" Button
self.btn1 = myButtonOne("Yes")
#Initialize GUI
self.layoutGUI()
self.initUI()
def initUI(self):
self.fromleft = 200
self.fromtop = 100
self.w = 1000
self.h = 500
self.setGeometry(self.fromleft, self.fromtop, self.w, self.h)
def layoutGUI(self):
hbox = QHBoxLayout()
hbox.setSpacing(20)
hbox.addWidget(self.btn1)
vbox = QVBoxLayout()
vbox.addWidget(self.titleLabel)
vbox.addLayout(hbox)
self.setLayout(vbox)
class myButtonOne(QPushButton):
def __init__(self, parent=None):
super(myButtonOne, self).__init__(parent)
# Set maximum border size
imSize = io.imread(imagePath)
imHeight = imSize.shape[1]
imWidth = imSize.shape[0]
# Set first button - The "Yes" Button
yesImage = someImagePath
self.setStyleSheet("background-image: url(" + yesImage + ");"
"background-repeat: none;"
"background-position: center;"
"border: none")
self.setFixedSize(imWidth, imHeight)
self.clicked.connect(self.buttonOnePushed)
def buttonOnePushed(self):
textView().show()
def enterEvent(self, event):
newImage = someOtherImagePath
self.setStyleSheet("background-image: url("+newImage+");"
"background-repeat: none;"
"background-position: center;"
"border: none")
def leaveEvent(self, event):
newImage = someImagePath
self.setStyleSheet("background-image: url("+newImage+");"
"background-repeat: none;"
"background-position: center;"
"border: none")
class textView(QWidget):
def __init(self):
textView.__init__()
theText = QLabel()
#define sizes
self.height = 550
self.width = 250
# Open QWidget
self.initUI()
# Set the text for the QLabel
someText = "Some Text for the label"
theText.setText(someText)
def initUI(self):
self.show()
# Start GUI
if __name__ == '__main__':
app = QApplication(sys.argv)
win = MainWindow()
win.show()
sys.exit(app.exec_())
So, I am trying to keep the QPushButton classes separate, so that I can customize them. I would like to keep it like that, especially to keep it clean and readable.
First off - please read: How to create a Minimal, Complete, and Verifiable example. I had a lot of work minimizing your code, which wasted a good amount of my time.
Nonetheless, here is a minimal working code, with your own button class:
import sys
from PyQt5.QtWidgets import QApplication, QPushButton, QWidget, QLabel, QVBoxLayout
class MainWindow(QWidget):
def __init__(self):
super(MainWindow, self).__init__()
self.titleLabel = QLabel( "some label text" )
self.btn1 = myButtonOne( "button text" )
hbox = QVBoxLayout() # one vertical box seemed enough
hbox.addWidget( self.titleLabel )
hbox.addWidget( self.btn1 )
self.setLayout( hbox )
class myButtonOne(QPushButton):
def __init__(self, text, parent=None):
super(myButtonOne, self).__init__(text, parent)
self.clicked.connect(self.buttonOnePushed)
# add your customizations here
def buttonOnePushed (self) :
self.t = textView()
self.t.show()
class textView(QWidget):
def __init__(self):
super(textView, self).__init__()
self.theText = QLabel('test', self )
if __name__ == '__main__':
app = QApplication(sys.argv)
win = MainWindow()
win.show()
sys.exit(app.exec_())
What have you done wrong in your code?
using textView().show() creates a local version of you textView-class and show()'s it:
def buttonOnePushed(self):
textView().show()
But, show() means that the code continues, where the end of your code comes, which results in cleaning up the locals. End - it's just shown for a microsecond.
def buttonOnePushed (self) :
self.t = textView()
self.t.show()
The code above stores the var as instance-attribute of the button, which is not cleaned up.
Furthermore you misspelled the init in your textView-class:
"__init" should be __init__ - else it is not called when using the constructor:
class textView(QWidget):
def __init(self):
textView.__init__()
Finally, you wanted to called show() twice:
in your textView-init you call initUI() which is calling show()
you calling show manually with textView().show()
Hope this helps! I did not include your personal style adjustments for readability.
I am getting started with creating GUI's in PyQt5 with Python 3. At the click of the button I want to run the "randomint" function and display the returned integer to the QLCDNumber named "lcd".
Here's my code:
import sys
from PyQt5.QtWidgets import QApplication, QWidget, QVBoxLayout, QPushButton, QLCDNumber
from random import randint
class Window(QWidget):
def __init__(self):
super().__init__()
self.initui()
def initui(self):
lcd = QLCDNumber(self)
button = QPushButton('Generate', self)
button.resize(button.sizeHint())
layout = QVBoxLayout()
layout.addWidget(lcd)
layout.addWidget(button)
self.setLayout(layout)
button.clicked.connect(lcd.display(self.randomint()))
self.setGeometry(300, 500, 250, 150)
self.setWindowTitle('Rand Integer')
self.show()
def randomint(self):
random = randint(2, 99)
return random
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = Window()
sys.exit(app.exec_())
I am getting the output:
TypeError: argument 1 has unexpected type 'NoneType'
How can I get the LCD to display the output from function "randomint"?
The problem is that the button.clicked.connect expects the slot (Python callable object), but lcd.display returns None. So we need a simple function (slot) for button.clicked.connect which will display your newly generated value. This is working version:
import sys
from PyQt5.QtWidgets import QApplication, QWidget, QVBoxLayout, QPushButton, QLCDNumber
from random import randint
class Window(QWidget):
def __init__(self):
super().__init__()
self.initui()
def initui(self):
self.lcd = QLCDNumber(self)
button = QPushButton('Generate', self)
button.resize(button.sizeHint())
layout = QVBoxLayout()
layout.addWidget(self.lcd)
layout.addWidget(button)
self.setLayout(layout)
button.clicked.connect(self.handleButton)
self.setGeometry(300, 500, 250, 150)
self.setWindowTitle('Rand Integer')
self.show()
def handleButton(self):
self.lcd.display(self.randomint())
def randomint(self):
random = randint(2, 99)
return random
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = Window()
sys.exit(app.exec_())
Another way of resolving the TypeError: argument 1 has unexpected type 'NoneType is to prefix your slot with lambda: like so:
self.tableWidget.cellChanged['int','int'].connect(lambda:self.somefunction())
I actually don't know why but it's a solution that worked for me.