I'm trying to build a date printer using Pyqt5 QDateEdit. I can popup the calendar, but I want to write the clicked date's string in the console (or in a label in window). I tried print(self.calendarWidget().document().toPlainText()) or print(self.calendarWidget().currentText()) but it didn't work.
I use this code;
from PyQt5 import QtCore, QtWidgets
class DateEdit(QtWidgets.QDateEdit):
popupSignal = QtCore.pyqtSignal()
def __init__(self, parent=None):
super(DateEdit, self).__init__(parent)
self.setCalendarPopup(True)
self.calendarWidget().installEventFilter(self)
def eventFilter(self, obj, event):
if self.calendarWidget() is obj and event.type() == QtCore.QEvent.Show:
self.popupSignal.emit()
return super(DateEdit, self).eventFilter(obj, event)
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
w = DateEdit()
w.popupSignal.connect(lambda: print("popup"))
w.show()
sys.exit(app.exec_())
What is its syntax? I didn't find enough documentation for it. Can you help please?
EDIT: The answer
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtGui import QPixmap
from PyQt5.QtWidgets import *
class MyWindow(QtWidgets.QWidget):
def __init__(self, parent=None):
super(MyWindow, self).__init__(parent)
self.dateEdit = QDateEdit(self)
self.lbl = QLabel()
self.dateEdit.setMaximumDate(QtCore.QDate(7999, 12, 28))
self.dateEdit.setMaximumTime(QtCore.QTime(23, 59, 59))
self.dateEdit.setCalendarPopup(True)
layout = QGridLayout()
layout.addWidget(self.dateEdit)
layout.addWidget(self.lbl)
self.setLayout(layout)
self.dateEdit.dateChanged.connect(self.onDateChanged)
def onDateChanged(self, qDate):
print('{0}/{1}/{2}'.format(qDate.day(), qDate.month(), qDate.year()))
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
app.setApplicationName('MyWindow')
main = MyWindow()
main.show()
sys.exit(app.exec_())
Related
I would like to obtain a calendar displaing only years and months.
In this link PyQt Calendar with only year/month view there is what I would like to obtain. I tried the solution but can't obtain the figure on the right (year/month) and what I get always opens the daily calendar
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtGui import QPixmap
from PyQt5.QtWidgets import *
class MyWindow(QtWidgets.QWidget):
def __init__(self, parent=None):
super(MyWindow, self).__init__(parent)
self.dateEdit = QtWidgets.QDateEdit()
self.dateEdit.setGeometry(QtCore.QRect(120, 40, 110, 23))
self.dateEdit.setCalendarPopup(True)
self.dateEdit.setObjectName("dateEdit")
self.dateEdit.dateChanged.connect(self.onDateChanged)
self.dateEdit.show()
_translate = QtCore.QCoreApplication.translate
self.dateEdit.setDisplayFormat(_translate("MyWindow", "MM/yyyy"))
def onDateChanged(self, qDate):
print('{0}/{1}/{2}'.format(qDate.day(), qDate.month(), qDate.year()))
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
app.setApplicationName('MyWindow')
main = MyWindow()
main.show()
sys.exit(app.exec_())
This is what I would like to obtain:
I am trying to use the QCalendarWidget but it doesn't render in the user interface as expected. The examples that I have seen show a calendar picker like object, but in my case I get a quite small rendering of a field. Here's what it looks like in the UI:
This is my first time using it so I am not sure if I am missing a step. Any thoughts on what I could be doing incorrectly? Here is the complete code being used:
from PyQt5.QtWidgets import QMainWindow, QCalendarWidget, QLabel
from PyQt5 import QtCore, QtWidgets, QtGui
import sys
class Example(QMainWindow):
def __init__(self):
super(Example, self).__init__()
self.initUI()
def initUI(self):
cal = QCalendarWidget(self)
cal.setGridVisible(True)
cal.move(20, 20)
cal.clicked[QtCore.QDate].connect(self.showDate)
self.lbl = QLabel(self)
date = cal.selectedDate()
self.lbl.setText(date.toString())
self.lbl.move(20, 200)
self.setGeometry(100,100,300,300)
self.setWindowTitle('Calendar')
self.show()
def showDate(self, date):
self.lbl.setText(date.toString())
def main():
app = QtWidgets.QApplication(sys.argv)
mainWin = Example()
mainWin.show()
sys.exit( app.exec_() )
if __name__ == '__main__':
main()
Use a layout, for example a QVBoxLayout, in the centralWidget of QMainWindow:
import sys
from PyQt5 import QtCore, QtGui, QtWidgets
class Example(QtWidgets.QMainWindow):
def __init__(self):
super(Example, self).__init__()
self.initUI()
def initUI(self):
cal = QtWidgets.QCalendarWidget(gridVisible=True)
cal.clicked.connect(self.showDate)
self.lbl = QtWidgets.QLabel()
date = cal.selectedDate()
self.lbl.setText(date.toString())
central_widget = QtWidgets.QWidget()
self.setCentralWidget(central_widget)
lay = QtWidgets.QVBoxLayout(central_widget)
lay.addWidget(cal)
lay.addWidget(self.lbl)
self.setGeometry(100, 100, 300, 300)
self.setWindowTitle("Calendar")
#QtCore.pyqtSlot(QtCore.QDate)
def showDate(self, date):
self.lbl.setText(date.toString())
def main():
app = QtWidgets.QApplication(sys.argv)
mainWin = Example()
mainWin.show()
sys.exit(app.exec_())
if __name__ == "__main__":
main()
Is a method to fit any image in view (that I import in QPixmap) and keep aspect ratio>. I try many solution but non of those works.
Also I don't not sure what I need to fit?
QGraphicsScene in QGraphicsView? Or QPixmap in QGraphicsView?
from PyQt5 import QtCore, QtGui, QtWidgets
class GraphicsView(QtWidgets.QGraphicsView):
def __init__(self, parent=None):
super(GraphicsView, self).__init__(parent)
scene = QtWidgets.QGraphicsScene()
self.setScene(scene)
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
w = GraphicsView()
photo = QtGui.QPixmap("image.jpg")
w.scene().addPixmap(photo)
w.resize(640, 480)
w.show()
sys.exit(app.exec_())
You have to use the fitInView() method of QGraphicsView in the resizeEvent() method of QGraphicsView:
from PyQt5 import QtCore, QtGui, QtWidgets
class GraphicsView(QtWidgets.QGraphicsView):
def __init__(self, parent=None):
super(GraphicsView, self).__init__(parent)
scene = QtWidgets.QGraphicsScene(self)
self.setScene(scene)
self.m_pixmap_item = self.scene().addPixmap(QtGui.QPixmap())
def setPixmap(self, pixmap):
self.m_pixmap_item.setPixmap(pixmap)
def resizeEvent(self, event):
if not self.m_pixmap_item.pixmap().isNull():
self.fitInView(self.m_pixmap_item, QtCore.Qt.KeepAspectRatio)
super(GraphicsView, self).resizeEvent(event)
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
w = GraphicsView()
photo = QtGui.QPixmap("image.jpg")
w.setPixmap(photo)
w.resize(640, 480)
w.show()
sys.exit(app.exec_())
I have five tool buttons in a QToolbar via toolbar.addAction() and if I choose one of them I would like to make the others not looking checked.
Example: If I choose the 'A' button and the program is now in the 'A' mode, others can't work.
You have to use a QActionGroup, you must also activate the checkable property of the QAction:
import sys
from PyQt5 import QtCore, QtGui, QtWidgets
class ToolDemo(QtWidgets.QMainWindow):
def __init__(self, parent=None):
super(ToolDemo, self).__init__(parent)
self.setWindowTitle("toolbar demo")
toolbarBox = QtWidgets.QToolBar(self)
toolbarBox.setFixedWidth(180)
self.addToolBar(QtCore.Qt.RightToolBarArea, toolbarBox)
vscode_action = QtWidgets.QAction("VSCode", self, checkable=True)
ptt_action = QtWidgets.QAction("Ppt", self, checkable=True)
word_action = QtWidgets.QAction("Word", self, checkable=True)
excel_action = QtWidgets.QAction("Excel", self, checkable=True)
other_action = QtWidgets.QAction("other", self, checkable=True)
group = QtWidgets.QActionGroup(self, exclusive=True)
for action in (
vscode_action,
ptt_action,
word_action,
excel_action,
other_action,
):
toolbarBox.addAction(action)
group.addAction(action)
def main():
app = QtWidgets.QApplication(sys.argv)
ex = ToolDemo()
ex.show()
sys.exit(app.exec_())
if __name__ == "__main__":
main()
Update:
If you want to use buttons like QCheckBox, QRadioButton, QPushButton and QToolButton are exclusive in the QToolBar then you must use QButtonGroup:
import sys
from PyQt5 import QtCore, QtGui, QtWidgets
class ToolDemo(QtWidgets.QMainWindow):
def __init__(self, parent=None):
super(ToolDemo, self).__init__(parent)
self.setWindowTitle("toolbar demo")
toolbarBox = QtWidgets.QToolBar(self)
toolbarBox.setFixedWidth(180)
self.addToolBar(QtCore.Qt.RightToolBarArea, toolbarBox)
vscode_button = QtWidgets.QCheckBox(self, text="VSCode", checkable=True)
ptt_button = QtWidgets.QCheckBox(self, text="Ppt", checkable=True)
word_button = QtWidgets.QRadioButton(self, text="Word", checkable=True)
excel_button = QtWidgets.QPushButton(self, text="Excel", checkable=True)
other_button = QtWidgets.QToolButton(self, text="other", checkable=True)
group = QtWidgets.QButtonGroup(self, exclusive=True)
for button in (
vscode_button,
ptt_button,
word_button,
excel_button,
other_button,
):
toolbarBox.addWidget(button)
group.addButton(button)
def main():
app = QtWidgets.QApplication(sys.argv)
ex = ToolDemo()
ex.show()
sys.exit(app.exec_())
if __name__ == "__main__":
main()
I am using Python3.6 and PySide2
I have a treewidget-A populated with employee list.
on click on employee (treewidget-A item) a another treeWidget-B will populate.
Now if I click on empty area (deselect item) but treeWidget-B still showing last clicked employee item details.
This is to populate treewidget items
self.treeWidget_A.itemClicked.connect(self.populate_employee)
self.treeWidget_A.currentItemChanged.connect(self.populate_employee)
How to execute clear_employee_data() function on click on empty area of QtreeWidget ?
def clear_employee_data(self):
self.treeWidget_B.clear()
You have to detect the click and verify that there is not an item:
from PySide2 import QtCore, QtWidgets
class TreeWidget(QtWidgets.QTreeWidget):
emptyClicked = QtCore.Signal()
def __init__(self, parent=None):
super(TreeWidget, self).__init__(parent)
for i in range(2):
it = QtWidgets.QTreeWidgetItem(self, ["item-{}".format(i)])
for j in range(3):
child_it = QtWidgets.QTreeWidgetItem(it, ["item-{}-{}".format(i, j)])
self.expandAll()
def mousePressEvent(self, event):
super(TreeWidget, self).mousePressEvent(event)
if not self.indexAt(event.pos()).isValid():
self.emptyClicked.emit()
#QtCore.Slot()
def on_empty_clicked():
print("clicked")
if __name__ == '__main__':
import sys
app = QtWidgets.QApplication(sys.argv)
w = TreeWidget()
w.emptyClicked.connect(on_empty_clicked)
w.resize(640, 480)
w.show()
sys.exit(app.exec_())
With Qt Designer use eventfilter:
from PySide2 import QtCore, QtGui, QtWidgets
from design import Ui_MainWindow
class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
emptyClicked = QtCore.Signal()
def __init__(self, parent=None):
super(MainWindow, self).__init__(parent)
self.setupUi(self)
self.treeWidget_A.viewport().installEventFilter(self)
self.emptyClicked.connect(self.on_emptyClicked)
def eventFilter(self, obj, event):
if obj is self.treeWidget_A.viewport() and event.type() == QtCore.QEvent.MouseButtonPress:
if not self.treeWidget_A.indexAt(event.pos()).isValid():
self.emptyClicked.emit()
return super(MainWindow, self).eventFilter(obj, event)
#QtCore.Slot()
def on_emptyClicked(self):
print("empty")
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
w = MainWindow()
w.show()
sys.exit(app.exec_())