QDateEdit widget does not respond to setSelectedSection

Why setSelectedSection doesn't work in __init__ and how to fix it
Heads up! You've already completed this tutorial.

I'm using QDateEdit and want to set the default selected section to the day. After calling setSelectedSection(DaySection), the currentSectionIndex() returns the correct value, but the display and arrow keys still behave as if the month section is selected. Is this a bug or am I reading the documentation incorrectly?

This is a common source of confusion when working with QDateEdit (or QDateTimeEdit) in PyQt5. The short answer is: setSelectedSection() requires the widget to have focus, and during __init__ the widget hasn't been shown or focused yet, so the call appears to do nothing.

Why setSelectedSection doesn't work during init

The setSelectedSection() method changes which part of the date (month, day, year) is visually selected and responds to arrow key input. Under the hood, this involves updating the widget's internal selection state, which depends on the widget being fully realized on screen and having keyboard focus.

When you call setSelectedSection() inside __init__, the widget hasn't been displayed yet. Qt hasn't finished laying everything out, and the widget doesn't have focus. So even though currentSectionIndex() reports the updated value, the visual state and keyboard behavior haven't actually changed.

This isn't a bug — it's a timing issue. The widget simply isn't ready to accept a section selection at that point in its lifecycle.

The fix: delay the call with QTimer.singleShot

The solution is to defer the setSelectedSection() call until after the event loop has started and the widget is visible and ready. You can do this with QTimer.singleShot(0, ...), which schedules a function to run as soon as the event loop is free:

python
from PyQt5.QtCore import QTimer

# Inside your __init__, after self.show():
QTimer.singleShot(0, lambda: self.dateEdit.setSelectedSection(qtw.QDateTimeEdit.DaySection))

A timeout of 0 doesn't mean "run immediately" — it means "run on the next pass of the event loop," which is exactly what we need. By that point the widget is visible and can properly handle the section selection.

You also need to give the widget focus so that the selection is actually active:

python
QTimer.singleShot(0, self.select_day_section)

With a helper method:

PyQt6 Crash Course by Martin Fitzpatrick — The important parts of PyQt6 in bite-size chunks

See the course

python
def select_day_section(self):
    self.dateEdit.setFocus()
    self.dateEdit.setSelectedSection(qtw.QDateTimeEdit.DaySection)

Complete working example

Here's the full corrected version. This example uses signals and slots to connect the dateChanged signal to a handler method, and basic PyQt5 widgets like QLabel to display the result.

python
import sys
import PyQt5.QtWidgets as qtw
import PyQt5.QtCore as qtc


class Window(qtw.QMainWindow):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("QDateEdit")
        self.setGeometry(100, 100, 500, 400)

        self.dateEdit = qtw.QDateEdit(self, calendarPopup=True)
        self.dateEdit.setGeometry(100, 100, 150, 40)
        self.label1 = qtw.QLabel("", self)
        self.label1.setGeometry(100, 150, 200, 60)
        self.label2 = qtw.QLabel("", self)
        self.label2.setGeometry(100, 170, 200, 60)

        self.dateEdit.dateChanged.connect(self.date_changed)
        self.dateEdit.setDate(qtc.QDate.currentDate())
        self.dateEdit.setDisplayFormat('MM-dd-yy')

        self.show()

        # Defer the section selection until the widget is visible and ready.
        qtc.QTimer.singleShot(0, self.select_day_section)

    def select_day_section(self):
        self.dateEdit.setFocus()
        self.dateEdit.setSelectedSection(qtw.QDateTimeEdit.DaySection)
        si = self.dateEdit.currentSectionIndex()
        print(f"After deferred setSelectedSection: currentSectionIndex({si})")

    def date_changed(self):
        str_date = self.dateEdit.date().toString(qtc.Qt.ISODate)
        self.label1.setText(f"changed date({str_date})")
        si = self.dateEdit.currentSectionIndex()
        self.label2.setText(f"currentSectionIndex({si})")


app = qtw.QApplication(sys.argv)
window = Window()
sys.exit(app.exec())

When you run this, the QDateEdit widget will open with the day section selected, and pressing the up/down arrow keys will change the day value as expected.

Summary

When working with QDateEdit or QDateTimeEdit, keep in mind that methods which affect visual selection state — like setSelectedSection() — need the widget to be visible and focused. If you call them too early (during __init__, before show()), they won't have the intended effect. Using QTimer.singleShot(0, ...) is a reliable way to defer these calls until the widget is ready.

Over 15,000 developers have bought Create GUI Applications with Python & Qt!
Create GUI Applications with Python & Qt5
Get the book

Downloadable ebook (PDF, ePub) & Complete Source code

Well done, you've finished this tutorial! Mark As Complete
[[ user.completed.length ]] completed [[ user.streak+1 ]] day streak
Martin Fitzpatrick

QDateEdit widget does not respond to setSelectedSection was written by Martin Fitzpatrick.

Martin Fitzpatrick has been developing Python/Qt apps for 8 years. Building desktop applications to make data-analysis tools more user-friendly, Python was the obvious choice. Starting with Tk, later moving to wxWidgets and finally adopting PyQt. Martin founded PythonGUIs to provide easy to follow GUI programming tutorials to the Python community. He has written a number of popular Python books on the subject.