Home | All Classes | Main Classes | Annotated | Grouped Classes | Functions |

# Setting Options

We provide an options dialog so that the user can set options that apply to all data sets in one place.

(Extracts from `optionsform.h`.)

        class OptionsForm : public QDialog
        {
            Q_OBJECT
        public:
            OptionsForm( QWidget* parent = 0, const char* name = "options form",
                         bool modal = FALSE, WFlags f = 0 );
            ~OptionsForm() {}

            QFont font() const { return m_font; }
            void setFont( QFont font );

            QLabel *chartTypeTextLabel;
            QComboBox *chartTypeComboBox;
            QPushButton *fontPushButton;
            QLabel *fontTextLabel;
            QFrame *addValuesFrame;
            QButtonGroup *addValuesButtonGroup;
            QRadioButton *noRadioButton;
            QRadioButton *yesRadioButton;
            QRadioButton *asPercentageRadioButton;
            QLabel *decimalPlacesTextLabel;
            QSpinBox *decimalPlacesSpinBox;
            QPushButton *okPushButton;
            QPushButton *cancelPushButton;

        protected slots:
            void chooseFont();

        protected:
            QVBoxLayout *optionsFormLayout;
            QHBoxLayout *chartTypeLayout;
            QHBoxLayout *fontLayout;
            QVBoxLayout *addValuesFrameLayout;
            QVBoxLayout *addValuesButtonGroupLayout;
            QHBoxLayout *decimalPlacesLayout;
            QHBoxLayout *buttonsLayout;

        private:
            QFont m_font;
        };

The layout of this dialog is slightly more complicated than for the set data form, but we only need a single slot. Unlike the "smart" set data form this is a "dumb" dialog that simply provides the widgets for the caller to set and read. The caller is responsible for updating things based on the changes the user makes.

(Extracts from `optionsform.cpp`.)

        #include "images/options_horizontalbarchart.xpm"
        #include "images/options_piechart.xpm"
        #include "images/options_verticalbarchart.xpm"

We include some some pixmaps to use in the chart type combobox.

## The Constructor

        OptionsForm::OptionsForm( QWidget* parent, const char* name,
                                  bool modal, WFlags f )
            : QDialog( parent, name, modal, f )
        {
            setCaption( "Chart -- Options" );
            resize( 320, 290 );

We pass all the arguments on to the QDialog constructor, set a caption and set an initial size.

The layout of the form will be to have the chart type label and combo box in a horizontal box layout, and similarly for the font button and font label, and for the decimal places label and spinbox. The buttons will also be placed in a horizontal layout, but with a spacer to move them to the right. The show values radio buttons will be vertically aligned within a frame. All of these will be laid out in a vertical box layout.

            optionsFormLayout = new QVBoxLayout( this, 11, 6 );

All the widgets will be laid out within the form's vertical box layout.

            chartTypeLayout = new QHBoxLayout( 0, 0, 6 );

The chart type label and combobox will be laid out side by side.

            chartTypeTextLabel = new QLabel( "&Chart Type", this );
            chartTypeLayout->addWidget( chartTypeTextLabel );

            chartTypeComboBox = new QComboBox( false, this );
            chartTypeComboBox->insertItem( QPixmap( options_piechart ), "Pie Chart" );
            chartTypeComboBox->insertItem( QPixmap( options_verticalbarchart ),
                                           "Vertical Bar Chart" );
            chartTypeComboBox->insertItem( QPixmap( options_horizontalbarchart ),
                                           "Horizontal Bar Chart" );
            chartTypeLayout->addWidget( chartTypeComboBox );
            optionsFormLayout->addLayout( chartTypeLayout );

We create the chart type label (with an accelerator which we'll relate to the chart type combobox later). We also create a chart type combobox, populating it with both pixmaps and text. We add them both to the horizontal layout and add the horizontal layout to the form's vertical layout.

            fontLayout = new QHBoxLayout( 0, 0, 6 );

            fontPushButton = new QPushButton( "&Font...", this );
            fontLayout->addWidget( fontPushButton );
            QSpacerItem* spacer = new QSpacerItem( 0, 0,
                                                   QSizePolicy::Expanding,
                                                   QSizePolicy::Minimum );
            fontLayout->addItem( spacer );

            fontTextLabel = new QLabel( this ); // Must be set by caller via setFont()
            fontLayout->addWidget( fontTextLabel );
            optionsFormLayout->addLayout( fontLayout );

We create a horizontal box layout to hold the font button and font label. The font button is straight-forward. We add a spacer to improve the appearance. The font text label is initially empty (since we don't know what font the user is using).

            addValuesFrame = new QFrame( this );
            addValuesFrame->setFrameShape( QFrame::StyledPanel );
            addValuesFrame->setFrameShadow( QFrame::Sunken );
            addValuesFrameLayout = new QVBoxLayout( addValuesFrame, 11, 6 );

            addValuesButtonGroup = new QButtonGroup( "Show Values", addValuesFrame );
            addValuesButtonGroup->setColumnLayout(0, Qt::Vertical );
            addValuesButtonGroup->layout()->setSpacing( 6 );
            addValuesButtonGroup->layout()->setMargin( 11 );
            addValuesButtonGroupLayout = new QVBoxLayout(
                                                addValuesButtonGroup->layout() );
            addValuesButtonGroupLayout->setAlignment( Qt::AlignTop );

            noRadioButton = new QRadioButton( "&No", addValuesButtonGroup );
            noRadioButton->setChecked( true );
            addValuesButtonGroupLayout->addWidget( noRadioButton );

            yesRadioButton = new QRadioButton( "&Yes", addValuesButtonGroup );
            addValuesButtonGroupLayout->addWidget( yesRadioButton );

            asPercentageRadioButton = new QRadioButton( "As &Percentage",
                                                        addValuesButtonGroup );
            addValuesButtonGroupLayout->addWidget( asPercentageRadioButton );
            addValuesFrameLayout->addWidget( addValuesButtonGroup );

The user may opt to display their own labels as they are or to add the values at the end of each label, either as-is or as percentages.

We create a frame to present the radio buttons in and create a layout for them. We create a button group (so that Qt will take care of handling the exclusive radio button behaviour automatically). Next we create the radio buttons, making "No" the default.

The decimal places label and spin box are laid out just like the other horizontal layouts, and the buttons are laid out in a very similar way to the buttons in the set data form.

            connect( fontPushButton, SIGNAL( clicked() ), this, SLOT( chooseFont() ) );
            connect( okPushButton, SIGNAL( clicked() ), this, SLOT( accept() ) );
            connect( cancelPushButton, SIGNAL( clicked() ), this, SLOT( reject() ) );

We only need three connections:

1. When the user clicks the font button we execute our own chooseFont() slot.
2. If the user clicks OK we call QDialog::accept(); it is up to the caller to read the data from the dialog's widgets and perform any necessary actions.
3. If the user clicks Cancel we call QDialog::reject().

            chartTypeTextLabel->setBuddy( chartTypeComboBox );
            decimalPlacesTextLabel->setBuddy( decimalPlacesSpinBox );

We use the setBuddy() function to associate widgets with label accelerators.

## The Slots

        void OptionsForm::chooseFont()
        {
            bool ok;
            QFont font = QFontDialog::getFont( &ok, m_font, this );
            if ( ok )
                setFont( font );
        }

When the user clicks the Font button this slot is invoked. It simply calls the static QFontDialog::getFont() function to obtain the user's choice of font. If they chose a font we call our setFont() slot which will present a textual description of the font in the font label.

        void OptionsForm::setFont( QFont font )
        {
            QString label = font.family() + " " +
                            QString::number( font.pointSize() ) + "pt";
            if ( font.bold() )
                label += " Bold";
            if ( font.italic() )
                label += " Italic";
            fontTextLabel->setText( label );
            m_font = font;
        }

This function displays a textual description of the chosen font in the font label and holds a copy of the font in the `m_font` member. We need the font in a member so that we can provide a default font for chooseFont().

« Taking Data | Contents | The Project File »