20

For a built-in dialog like QInputDialog, I've read that I can do this:

text, ok = QtGui.QInputDialog.getText(self, 'Input Dialog', 'Enter your name:')

How can I emulate this behavior using a dialog that I design myself in Qt Designer? For instance, I would like to do:

my_date, my_time, ok = MyCustomDateTimeDialog.get_date_time(self)
Thomas Johnson
  • 10,776
  • 18
  • 60
  • 98

2 Answers2

32

Here is simple class you can use to prompt for date:

class DateDialog(QDialog):
    def __init__(self, parent = None):
        super(DateDialog, self).__init__(parent)

        layout = QVBoxLayout(self)

        # nice widget for editing the date
        self.datetime = QDateTimeEdit(self)
        self.datetime.setCalendarPopup(True)
        self.datetime.setDateTime(QDateTime.currentDateTime())
        layout.addWidget(self.datetime)

        # OK and Cancel buttons
        buttons = QDialogButtonBox(
            QDialogButtonBox.Ok | QDialogButtonBox.Cancel,
            Qt.Horizontal, self)
        buttons.accepted.connect(self.accept)
        buttons.rejected.connect(self.reject)
        layout.addWidget(buttons)

    # get current date and time from the dialog
    def dateTime(self):
        return self.datetime.dateTime()

    # static method to create the dialog and return (date, time, accepted)
    @staticmethod
    def getDateTime(parent = None):
        dialog = DateDialog(parent)
        result = dialog.exec_()
        date = dialog.dateTime()
        return (date.date(), date.time(), result == QDialog.Accepted)

and to use it:

date, time, ok = DateDialog.getDateTime()
hluk
  • 5,848
  • 2
  • 21
  • 19
  • Can you explain why you use the `@staticmethod` decorator, and why you chose to instantiate the `DateDialog` class within the `DateDialog` class definition? I found this a bit confusing. – wesanyer Feb 22 '16 at 18:39
  • @wesanyer True. You can use straightforward function to create the dialog and get the result which is better (if you don't need to reuse the dialog class).Also it could return just the `date` object and return `None` or throw exception if dialog was canceled (not sure what is the right solution in Python). – hluk Feb 23 '16 at 07:17
  • For anyone that doesn't know, QDialog can be imported as follows: `from PyQt4.QtGui import QDialog` (assuming you are using PyQt version 4) – MD004 Dec 01 '16 at 18:20
28

I tried to edit the answer of hluk with the changes below but it got rejected, not sure why because it got some clear bugs as far is I can see.

bugfix 1: removed self. from self.layout.addWidget(self.buttons)

bugfix 2: connected OK and Cancel buttons to its correct actions

enhancement: made the code ready to run by including the imports and improved the run example

from PyQt4.QtGui import QDialog, QVBoxLayout, QDialogButtonBox, QDateTimeEdit, QApplication
from PyQt4.QtCore import Qt, QDateTime

class DateDialog(QDialog):
    def __init__(self, parent = None):
        super(DateDialog, self).__init__(parent)

        layout = QVBoxLayout(self)

        # nice widget for editing the date
        self.datetime = QDateTimeEdit(self)
        self.datetime.setCalendarPopup(True)
        self.datetime.setDateTime(QDateTime.currentDateTime())
        layout.addWidget(self.datetime)

        # OK and Cancel buttons
        self.buttons = QDialogButtonBox(
            QDialogButtonBox.Ok | QDialogButtonBox.Cancel,
            Qt.Horizontal, self)
        layout.addWidget(self.buttons)

        self.buttons.accepted.connect(self.accept)
        self.buttons.rejected.connect(self.reject)

    # get current date and time from the dialog
    def dateTime(self):
        return self.datetime.dateTime()

    # static method to create the dialog and return (date, time, accepted)
    @staticmethod
    def getDateTime(parent = None):
        dialog = DateDialog(parent)
        result = dialog.exec_()
        date = dialog.dateTime()
        return (date.date(), date.time(), result == QDialog.Accepted)

and to use it:

app = QApplication([])
date, time, ok = DateDialog.getDateTime()
print("{} {} {}".format(date, time, ok))
app.exec_()
lou
  • 1,740
  • 1
  • 13
  • 13