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.
Related
I use the following code to set a PySide6 app to the minimal possible size. This works fine when increasing the size of the widgets (set - to + in line 37), but not when decreasing it - in effect, the size of the windows does decrease, but it seems to be one step late.
I found a few workarounds, most notably in Qt Layout, resize to minimum after widget size changes, but none of what I tried seems to be working (and I have met other issues with app.processEvents(), which should be avoided anyway).
Edit: In the new code example below, I think the problem is the width of the QPushButton, which is calculated too late.
Interestingly, this width of the QPushButton is solved by the layout.setSizeConstraint(QLayout.SetFixedSize) workaround, but the window width is not.
app.processEvents() works for this example, but I see bad side effects on other signals when using it.
New code example:
from PySide6.QtCore import Qt
from PySide6.QtGui import QPixmap
from PySide6.QtWidgets import (QApplication, QLabel, QLayout, QMainWindow,
QPushButton, QVBoxLayout, QWidget)
class Window(QMainWindow):
def __init__(self):
super().__init__()
self.i = 0
self.button = QPushButton("push me!")
self.button.clicked.connect(self.clicked)
self.label = QLabel()
layout = QVBoxLayout()
layout.addWidget(self.button)
layout.addWidget(self.label)
# https://stackoverflow.com/a/21458822/880783
# layout.setSizeConstraint(QLayout.SetFixedSize) # (ineffective)
widget = QWidget()
widget.setLayout(layout)
self.setCentralWidget(widget)
self.setWindowFlag(Qt.MSWindowsFixedSizeDialogHint)
self.clicked()
self.show()
def clicked(self):
npix = 500 - 50 * self.i
self.label.setPixmap(QPixmap(npix, npix))
# app.processEvents() # (effective, but discouraged)
self.adjustSize()
self.i += 1
app = QApplication()
win = Window()
app.exec()
Original code example:
import threading
import time
from PySide6.QtCore import Qt
from PySide6.QtGui import QPixmap
from PySide6.QtWidgets import (
QApplication,
QHBoxLayout,
QLabel,
QLayout,
QMainWindow,
QWidget,
)
class Window(QMainWindow):
def __init__(self):
super().__init__()
self.label = QLabel()
layout = QHBoxLayout()
layout.addWidget(self.label)
# https://stackoverflow.com/a/21458822/880783
# layout.setSizeConstraint(QLayout.SetFixedSize) # (ineffective)
widget = QWidget()
widget.setLayout(layout)
self.setCentralWidget(widget)
self.setWindowFlag(Qt.MSWindowsFixedSizeDialogHint)
self.show()
def run(self):
for i in range(10):
npix = 500 - 50 * i
self.label.setPixmap(QPixmap(npix, npix))
# app.processEvents() # (ineffective)
self.adjustSize()
time.sleep(1)
app = QApplication()
threading.Thread(target=Window().run).start()
app.exec()
#musicamante has posted very helpful comments, which I now turn into an answer.
Basically, this code works great:
from PySide6.QtCore import QMetaObject, Qt, QTimer, Slot
from PySide6.QtGui import QPixmap
from PySide6.QtWidgets import (QApplication, QLabel, QMainWindow, QPushButton,
QVBoxLayout, QWidget)
class Window(QMainWindow):
def __init__(self):
super().__init__()
self.i = 0
self.button = QPushButton("push me!")
self.button.clicked.connect(self.clicked)
self.label = QLabel()
layout = QVBoxLayout()
layout.addWidget(self.button)
layout.addWidget(self.label)
widget = QWidget()
widget.setLayout(layout)
self.setCentralWidget(widget)
self.setWindowFlag(Qt.MSWindowsFixedSizeDialogHint)
self.clicked()
self.show()
# #Slot()
# def adjustSize(self):
# super().adjustSize()
def clicked(self):
npix = 500 - 50 * self.i
self.label.setPixmap(QPixmap(npix, npix))
self.i += 1
# # As in https://stackoverflow.com/a/23954088/880783 - does not work
# QMetaObject.invokeMethod(self, "adjustSize")
# This works!
QTimer.singleShot(0, self.adjustSize)
app = QApplication()
win = Window()
app.exec()
As one can see, I have also tried the approach put forward https://stackoverflow.com/a/23954088/880783 - without success, however.
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())
This question already has an answer here:
How to open a window with a click of a button from another window using PyQt?
(1 answer)
Closed 3 years ago.
I want to create a new window when a button is clicked. I will later have windows be created dynamically depending on inputted data. But I want to start simple first.
from PyQt5 import QtWidgets
from PyQt5.QtWidgets import QPushButton, QGridLayout, QWidget
class MyWindow(QtWidgets.QMainWindow, QPushButton):
def __init__(self):
super(MyWindow, self).__init__()
centralWidget = QWidget()
self.setCentralWidget(centralWidget)
self.setWindowTitle("ASSET")
self.Button = QPushButton('Action',self)
self.Button.clicked.connect(self.Action)
self.layout = QGridLayout(centralWidget)
self.layout.addWidget(self.Button)
def Action(self):
pass
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
window = MyWindow()
window.show()
sys.exit(app.exec_())
You can create another QMainWindow() and when the button is clicked, activate the show() method
from PyQt5 import QtWidgets
from PyQt5.QtWidgets import QPushButton, QGridLayout, QWidget, QLabel
class NewWindow(QtWidgets.QMainWindow):
def __init__(self, parent=None):
super(NewWindow, self).__init__(parent)
self.label = QLabel('New Window!')
centralWidget = QWidget()
self.setCentralWidget(centralWidget)
self.layout = QGridLayout(centralWidget)
self.layout.addWidget(self.label)
class MyWindow(QtWidgets.QMainWindow, QPushButton):
def __init__(self):
super(MyWindow, self).__init__()
centralWidget = QWidget()
self.setCentralWidget(centralWidget)
self.setWindowTitle("ASSET")
self.Button = QPushButton('Action',self)
self.Button.clicked.connect(self.Action)
self.layout = QGridLayout(centralWidget)
self.layout.addWidget(self.Button)
self.new_window = NewWindow(self)
def Action(self):
self.new_window.show()
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
window = MyWindow()
window.show()
sys.exit(app.exec_())
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()"""
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.