Archivio

Posts Tagged ‘pytyhon’

PyQt5: QDate

8 Aprile 2019 Commenti chiusi

Torna all’indice degli appunti

QDate

QDate è una classe che mette a disposizione un set di metodi per la gestione delle date.
E’ disponibile anche un widget Calendar per la rappresentazione delle stesse.

La costruzione dell’oggetto date si ottiene passando al costruttore gli argomenti year, month, day:

>>> date = QDate(2019, 3, 30)

Con il metodo getDate si ottiene la data impostata

>>> date.getDate()
(2019, 3, 30)

Per modificare un oggetto data già esistente si utilizza il metodo setDate(year, month, day):

>>> date.setDate(2019,3,31)
True
>>> date.getDate()
(2019, 3, 31)

Anno, mese e giorno sono ottenuti grazie ai metodi year, month, day dell’oggetto date:

>>> date.year()
2019
>>> date.month()
3
>>> date.day()
31

E’ possibile anche aggiungere anni, mesi e giorni all’oggetto date, con i metodi addYears(int), addMonths(int), addDays(int).

Nota:

Questi metodi però non modificano l’oggetto date esistente, ma ritornano un nuovo oggetto date con i valori modificati.

>>> date.addYears(1)
PyQt5.QtCore.QDate(2020, 3, 31)
>>> date.addMonths(2)
PyQt5.QtCore.QDate(2019, 5, 31)
>>> date.addDays(1)
PyQt5.QtCore.QDate(2019, 4, 1)
>>> date.getDate()
(2019, 3, 31)

Per scalare nella data, ovviamente si utilizzeranno numeri negativi:

>>> date.addDays(-3)
PyQt5.QtCore.QDate(2019, 3, 28)

Vediamo alcuni metodi utili della classe QDate:

dayOfWeek:
ritorna il numero del giorno della settimana:

>> date.getDate()
(2019, 3, 31)
>>> date.dayOfWeek()
7

dayOfYear
ritorna il numero del giorno dell’anno:

>>> date.dayOfYear()
90

daysInMonth e daysInYear:
ritorna il numero di giorni presenti nel mese e nell’anno dell’oggetto date corrente

>>> date.daysInMonth()
31
>>> date.daysInYear()
365

weekInYear
ritorna il numero della settimana nell’anno:

>>> date.weekNumber()
(13, 2019)

Se vogliamo conoscere il nome del giorno e del mese, possiamo utilzzare i seguenti metodi:

longDayName(dayofweek)
ritorna il nome del giorno della settimana in forma estesa

>>> date.longDayName(date.dayOfWeek())
'domenica'

shortDayName(dayofweek)
ritorna il nome del giorno della settimana in forma abbreviata

>>> date.shortDayName(date.dayOfWeek())
'dom'

longMonthName(month)
ritorna il nome del mese in forma estesa

>>> date.longMonthName(date.month())
'marzo'

shortMonthName(month)
ritorna il nome del mese in forma abbreviata

>>> date.shortMonthName(date.month())
'mar'

E’ possibile sapere anche se un anno è bisestile, con il metodo isLeapYear(year):

>>> QDate.isLeapYear(date.year())
False
>>> QDate.isLeapYear(2020)
True

Per calcolare quanti giorni mancano ad una determinata data si utilizza il metodo daysTo(date):

>>> nextdate = date.addMonths(2)
>>> nextdate
PyQt5.QtCore.QDate(2019, 5, 31)
>>> date.daysTo(nextdate)
61

Per ottenere la data in forma di stringa, si utilizza il metodo toString

>>> date.toString()
'dom mar 31 2019'

CONFRONTI

I confronti tra date vengono effettuati con i comuni operatori:

>>> date > nextdate
False
>>> date < nextdate
True
>>> samedate = nextdate.addMonths(-2)
>>> date == samedate
True

DATA CORRENTE

Si ottiene con il metodo currentDate

>>> QDate.currentDate()
PyQt5.QtCore.QDate(2019, 3, 31)

E’ possibile controllare che una data sia esistente, con il metodo isValid(year, month, day)

>>> QDate.isValid(2019, 2, 30)
False
>>> QDate.isValid(2019, 2, 28)
True

CONVERSIONE DA DATA A STRINGA

E’ possibile convertire un oggetto QDate in formato stringa con il metodo toString(format) dove format rappresenta
il tipo di formato utilizzato per la conversione.
format può assumere i seguenti patterns:

d il giorno rappresentato senza il leading zero (1-31);
dd il giorno rappresentato con il leading zero(01-31);
ddd nome del giorno abbreviato (‘Lun’-‘Dom’);
dddd nome del giorno esteso (‘Lunedì’-‘Domenica’);
M il mese rappresentato senza il leading zero (1-12);
MM il mese rappresentato con il leading zero (01-12);
MMM nome del mese abbreviato (‘Gen’-‘Dic’);
MMMM nome del mese esteso (‘Gennaio’-‘Dicembre’);
yy anno espresso con due cifre (00-99)
yyyy anno espresso per intero

>>> date.toString("d")
'31'
>>> date.toString("d M yy")
'31 3 19'
>>> date.toString("d/M/yy")
'31/3/19'
>>> date.toString("d/MM/yy")
'31/03/19'
>>> date.toString("dddd d MMMM yyyy")
'domenica 31 marzo 2019'

CONVERSIONE DA STRINGA A DATA

Inversamente della situazione precedente, è possibile convertire una stringa in oggetto QDate, con il metodo fromString(string, format),
dove string è ovviamente la data in formato stringa e format il tipo di formato utilizzato per la conversione.

>>> format = "dddd d MMMM yyyy"
>>> sdate = date.toString(format)
>>> sdate
'domenica 31 marzo 2019'
>>> newdate = QDate.fromString(sdate, format)
>>> newdate.getDate()
(2019, 3, 31)
>>> date == newdate
True
DATE WIDGET QDATEWIDGET

La classe QDateEdit ci mette a disposizione il primo widget per gestire gli oggetti QDate.
I metodi disponibili sono:

date(): ottiene la data mostrata nel widget;
setMinimumDate(QDate): definisce la data minima definibile dall’utente;
setMaximumDate(QDate): definisce la data massima definibile dall’utente;
minimumDate: ottiene il valore minimo impostato per il widget;
maximumDate: ottiene il valore massimo impostato per il widget;
setDisplayFormat(format): definisce il formato della data utilizzato dal widget;
displayFormat: ottiene il formato della data utilizzato dal widget;

from PyQt5.QtWidgets import QWidget, QApplication, QBoxLayout, QDateEdit
from PyQt5.QtCore import QDate
from PyQt5.QtWidgets import QMainWindow
import sys


class MainWindow(QMainWindow):
    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)
        self.setWindowTitle("QDate Example")
        self.central_widget = FormWidget(self)
        self.setCentralWidget(self.central_widget)
        self.resize(200, 75)


class FormWidget(QWidget):
    def __init__(self, parent):
        super(FormWidget, self).__init__(parent)
        layout = QBoxLayout(QBoxLayout.TopToBottom)
        date_edit = QDateEdit(QDate.currentDate())
        layout.addWidget(date_edit, 0)
        self.setLayout(layout)


if __name__ == '__main__':
    app = QApplication(sys.argv)
    main_window = MainWindow()
    main_window.show()
    sys.exit(app.exec_())

Con i metodi visti precedentemente possiamo affinare la visualizzazione ed il campo di utilizzo.
Usiamo il format degli esempi precedenti e limitiamo la modifica della data:

...
        date_edit = QDateEdit(QDate.currentDate())
        date_edit.setMinimumDate(QDate(2019, 4, 5))
        date_edit.setMaximumDate(QDate(2019, 4, 15))
        date_edit.setDisplayFormat("dddd dd/MM/yyyy")
...

SEGNALI

Il segnale degno di nota, oltre a quelli soliti ereditati, è dateChanged, emesso ad ogni modifica della data, da parte dell’utente, che sia un o un click sulle freccette del widget:

...
        date_edit.dateChanged.connect(self.on_date_changed)

    def on_date_changed(self):
        date_editor = self.sender()
        format = date_editor.displayFormat()
        newdate = date_editor.date().toString(format)
        print("[SIG] Date has changed to %s" % newdate)
        print("      Minimum time set: %s" % date_editor.minimumDate())
        print("      Maximum time set: %s" % date_editor.maximumDate())
        print("      date format is  : %s" % format)
...
CALENDARIO

Il widget utilizzato per gestire le date è QCalendarWidget.
I metodi di QCalendarWidget sono i seguenti:

showToday(): mostra la data corrente sul calendario (metodo chiamato di default);
showSelectedDate(): mostra la data selezionata;
showNextMonth(): mostra sul calendario il mese successivo a quello corrente;
showNextYear(): mostra sul calendario la stessa data sull’anno successivo;
showPreviousMonth(): mostra il mese precedente a quello corrente;
showPreviousYear(): mostra sul calendario la stessa data nell’anno precedente;

from PyQt5.QtWidgets import QWidget, QApplication, QBoxLayout, QCalendarWidget
from PyQt5.QtWidgets import QMainWindow
import sys


class MainWindow(QMainWindow):
    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)
        self.setWindowTitle("QCalendar Example")
        self.central_widget = FormWidget(self)
        self.setCentralWidget(self.central_widget)
        self.resize(200, 200)


class FormWidget(QWidget):
    def __init__(self, parent):
        super(FormWidget, self).__init__(parent)
        layout = QBoxLayout(QBoxLayout.TopToBottom)

        calendar = QCalendarWidget()

        layout.addWidget(calendar, 0)
        self.setLayout(layout)


if __name__ == '__main__':
    app = QApplication(sys.argv)
    main_window = MainWindow()
    main_window.show()
    sys.exit(app.exec_())

Sulla barra della data sono selezionabili sia il mese (oltre alle freccette), sia l’anno.

Se vogliamo limitare il range di date entro cui il calendario può spostarsi, possiamo utilizzare i metodi:
setMinimumDate(QDate): per settare la minima data oltre la quale il calendario non può scendere;
setMaximumDate(QDate): per settare la massima data oltre la quale il calendario non può andare;

from PyQt5.QtCore import QDate
...
        calendar = QCalendarWidget()
        layout.addWidget(calendar, 0)
        self.setLayout(layout)
        calendar.setMinimumDate(QDate(2019, 3, 20))
        calendar.setMaximumDate(QDate(2019, 3, 25))
...

per conoscere quali date minima e massima sono state impostate, si utilizzano i metodi minimumDate e maximumDate.

>>> from PyQt5.QtCore import QDate
>>> calendar.setMinimumDate(QDate(2019, 3, 20))
>>> calendar.setMaximumDate(QDate(2019, 3, 25))
>>> calendar.minimumDate()
PyQt5.QtCore.QDate(2019, 3, 20)
>>> calendar.maximumDate()
PyQt5.QtCore.QDate(2019, 3, 25)

Per disattivare la barra di navigazione del calendario, si utilizza il metodo setNavigationBarVisible(bool).
Per rendere visibile la griglia invece si usa il metodo setGridVisible(bool)

...
        calendar = QCalendarWidget()
        calendar.setNavigationBarVisible(False)
        calendar.setGridVisible(True)
...

SEGNALI

I più importanti sono due, clicked e selectionChanged; la differenza tra i due è che,
il primo segnale viene emesso ad ogni click su una data, mentre il secondo solo se la data selezionata cambia rispetto a quella precedente.

...

        calendar.clicked.connect(self.on_click)
        calendar.selectionChanged.connect(self.on_selection_changed)

    def on_click(self):
        calendar = self.sender()
        date = calendar.selectedDate()
        s_date = date.toString("dddd d MMMM yyyy")
        print("[SIG] click on calendar on date: '%s'" % s_date)

    def on_selection_changed(self):
        calendar = self.sender()
        date = calendar.selectedDate()
        s_date = date.toString("dddd d MMMM yyyy")
        print("[SIG] selection changed: now date is: '%s'" % s_date)
...

Nota:
l’utilizzo di sender() è solo didattico per capire da chi arriva il segnale,
rendendo calendar attributo dell’istanza di QWidget (self.calendar) in fase di inizializzazione,
permetterebbe di risparmiare sulle linee di codice.

Torna all’indice degli appunti

Categorie:PyQt5, python Tag: ,