Calendar Example

Image non disponible

Specifically, the example demonstrates the following:

  • Use of a text editor with a text document

  • Insertion of tables and frames into a document

  • Navigation within a table

  • Insert text in different styles

The rich text editor used to display the document is used within a main window application.

MainWindow Class Definition

The MainWindow class provides a text editor widget and some controls to allow the user to change the month and year shown. The font size used for the text can also be adjusted.

 
Sélectionnez
class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow();

public slots:
    void setFontSize(int size);
    void setMonth(int month);
    void setYear(QDate date);

private:
    void insertCalendar();

    int fontSize;
    QDate selectedDate;
    QTextBrowser *editor;
};

The private insertCalendar() function performs most of the work, relying on the fontSize and selectedDate variables to write useful information to the editor.

MainWindow Class Implementation

The MainWindow constructor sets up the user interface and initializes variables used to generate a calendar for each month.

 
Sélectionnez
MainWindow::MainWindow()
{
    selectedDate = QDate::currentDate();
    fontSize = 10;

    QWidget *centralWidget = new QWidget;

We begin by setting default values for the selected date that will be highlighted in the calendar and the font size to be used. Since we are using a QMainWindow for the user interface, we construct a widget for use as the central widget.

The user interface will include a line of controls above the generated calendar; we construct a label and a combobox to allow the month to be selected, and a spin box for the year. These widgets are configured to provide a reasonable range of values for the user to try:

 
Sélectionnez
    QLabel *dateLabel = new QLabel(tr("Date:"));
    QComboBox *monthCombo = new QComboBox;

    for (int month = 1; month <= 12; ++month)
        monthCombo->addItem(QLocale::system().monthName(month));

    QDateTimeEdit *yearEdit = new QDateTimeEdit;
    yearEdit->setDisplayFormat("yyyy");
    yearEdit->setDateRange(QDate(1753, 1, 1), QDate(8000, 1, 1));

We use the selectedDate object to obtain the current month and year, and we set these in the combobox and spin box:

The font size is displayed in a spin box which we restrict to a sensible range of values:

 
Sélectionnez
    QLabel *fontSizeLabel = new QLabel(tr("Font size:"));
    QSpinBox *fontSizeSpinBox = new QSpinBox;
    fontSizeSpinBox->setRange(1, 64);

    editor = new QTextBrowser;
    insertCalendar();

We construct an editor and use the insertCalendar() function to create a calendar for it. Each calendar is displayed in the same text editor; in this example we use a QTextBrowser since we do not allow the calendar to be edited.

The controls used to set the month, year, and font size will not have any effect on the appearance of the calendar unless we make some signal-slot connections:

 
Sélectionnez
    connect(monthCombo, QOverload<int>::of(&QComboBox::activated),
            this, &MainWindow::setMonth);
    connect(yearEdit, &QDateTimeEdit::dateChanged,
            this, &MainWindow::setYear);
    connect(fontSizeSpinBox, QOverload<int>::of(&QSpinBox::valueChanged),
            this, &MainWindow::setFontSize);

The signals are connected to some simple slots in the MainWindow class which we will describe later.

We create layouts to manage the widgets we constructed:

 
Sélectionnez
    QHBoxLayout *controlsLayout = new QHBoxLayout;
    controlsLayout->addWidget(dateLabel);
    controlsLayout->addWidget(monthCombo);
    controlsLayout->addWidget(yearEdit);
    controlsLayout->addSpacing(24);
    controlsLayout->addWidget(fontSizeLabel);
    controlsLayout->addWidget(fontSizeSpinBox);
    controlsLayout->addStretch(1);

    QVBoxLayout *centralLayout = new QVBoxLayout;
    centralLayout->addLayout(controlsLayout);
    centralLayout->addWidget(editor, 1);
    centralWidget->setLayout(centralLayout);

    setCentralWidget(centralWidget);

Finally, the central widget is set for the window.

Each calendar is created for the editor by the insertCalendar() function which uses the date and font size, defined by the private selectedDate and fontSize variables, to produce a suitable plan for the specified month and year.

 
Sélectionnez
void MainWindow::insertCalendar()
{
    editor->clear();
    QTextCursor cursor = editor->textCursor();
    cursor.beginEditBlock();

    QDate date(selectedDate.year(), selectedDate.month(), 1);

We begin by clearing the editor's rich text document, and obtain a text cursor from the editor that we will use to add content. We also create a QDate object based on the currently selected date.

The calendar is made up of a table with a gray background color that contains seven columns: one for each day of the week. It is placed in the center of the page with equal space to the left and right of it. All of these properties are set in a QTextTableFormat object:

 
Sélectionnez
    QTextTableFormat tableFormat;
    tableFormat.setAlignment(Qt::AlignHCenter);
    tableFormat.setBackground(QColor("#e0e0e0"));
    tableFormat.setCellPadding(2);
    tableFormat.setCellSpacing(4);

Each cell in the table will be padded and spaced to make the text easier to read.

We want the columns to have equal widths, so we provide a vector containing percentage widths for each of them and set the constraints in the QTextTableFormat:

 
Sélectionnez
    QVector<QTextLength> constraints;
    constraints << QTextLength(QTextLength::PercentageLength, 14)
                << QTextLength(QTextLength::PercentageLength, 14)
                << QTextLength(QTextLength::PercentageLength, 14)
                << QTextLength(QTextLength::PercentageLength, 14)
                << QTextLength(QTextLength::PercentageLength, 14)
                << QTextLength(QTextLength::PercentageLength, 14)
                << QTextLength(QTextLength::PercentageLength, 14);
    tableFormat.setColumnWidthConstraints(constraints);

The constraints used for the column widths are only useful if the table has an appropriate number of columns. With the format for the table defined, we construct a new table with one row and seven columns at the current cursor position: