Sök…


Introduktion

QListView-widgeten är en del av Qt-programmets mekanismer för modell / vy. I grunden tillåter det att visa objekt lagrade i en modell i form av en lista. I det här ämnet kommer vi inte in djupet i Model / View-mekanismerna för Qt, utan snarare fokusera på den grafiska aspekten av en View-widget: QListView, och särskilt hur man lägger till en rubrik ovanpå detta objekt genom användning av QPaintEvent objekt.

Anpassad QListView-deklaration

/*!
 * \class MainMenuListView
 * \brief The MainMenuListView class is a QListView with a header displayed
 *        on top. 
 */
class MainMenuListView : public QListView
{
Q_OBJECT
    
    /*!
     * \class Header
     * \brief The header class is a nested class used to display the header of a
     *        QListView. On each instance of the MainMenuListView, a header will
     *        be displayed.
     */
    class Header : public QWidget
    {
    public:
        /*!
         * \brief Constructor used to defined the parent/child relation
         *        between the Header and the QListView.
         * \param parent Parent of the widget. 
         */
        Header(MainMenuListView* parent);

        /*!
         * \brief Overridden method which allows to get the recommended size 
         *        for the Header object.
         * \return The recommended size for the Header widget.
         */
        QSize sizeHint() const;

        protected:
        /*!
         * \brief Overridden paint event which will allow us to design the
         *        Header widget area and draw some text.
         * \param event Paint event.
         */
        void paintEvent(QPaintEvent* event);

    private:
        MainMenuListView* menu;    /*!< The parent of the Header. */
    };

public:
    /*!
     * \brief Constructor allowing to instanciate the customized QListView.
     * \param parent Parent widget.
     * \param header Text which has to be displayed in the header 
     *        (Header by default)
     */
    MainMenuListView(QWidget* parent = nullptr, const QString& header = QString("Header"));

    /*!
     * \brief Catches the Header paint event and draws the header with
     *        the specified text in the constructor.
     * \param event Header paint event.
     */
    void headerAreaPaintEvent(QPaintEvent* event);

    /*!
     * \brief Gets the width of the List widget.
     *        This value will also determine the width of the Header.
     * \return The width of the custom QListView.
     */
    int headerAreaWidth();

 protected:         
    /*!
     * \brief Overridden method which allows to resize the Header.
     * \param event Resize event.
     */
    void resizeEvent(QResizeEvent* event);

private:
   QWidget*    headerArea;    /*!< Header widget. */
   QString     headerText;    /*!< Header title. */
};

Implementering av den anpassade QListView

QSize MainMenuListView::Header::sizeHint() const
{
    // fontmetrics() allows to get the default font size for the widget.
    return QSize(menu->headerAreaWidth(), fontMetrics().height());
}

void MainMenuListView::Header::paintEvent(QPaintEvent* event)
{
    // Catches the paint event in the parent.
    menu->headerAreaPaintEvent(event);
}

MainMenuListView::MainMenuListView(QWidget* parent, const QString& header) : QListView(parent), headerText(header)
{
    headerArea = new Header(this);

    // Really important. The view port margins define where the content
    // of the widget begins.
    setViewportMargins(0, fontMetrics().height(), 0, 0);
}

void MainMenuListView::headerAreaPaintEvent(QPaintEvent* event)
{
    // Paints the background of the header in gray. 
    QPainter painter(headerArea);
    painter.fillRect(event->rect(), Qt::lightGray);

    // Display the header title in black.
    painter.setPen(Qt::black);

    // Writes the header aligned on the center of the widget. 
    painter.drawText(0, 0, headerArea->width(), fontMetrics().height(), Qt::AlignCenter, headerText);
}

int MainMenuListView::headerAreaWidth()
{
    return width();
}

void MainMenuListView::resizeEvent(QResizeEvent* event)
{
    // Executes default behavior.
    QListView::resizeEvent(event);
 
    // Really important. Allows to fit the parent width.   
    headerArea->adjustSize();
}

Användningsfall: MainWindow-deklaration

class MainMenuListView;

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget* parent = 0);
    ~MainWindow();

private:
    MainMenuListView* menuA;
    MainMenuListView* menuB;
    MainMenuListView* menuC;
};

Använd fall: Implementering

MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent)
{
    QWidget* w = new QWidget(this);

    QHBoxLayout* hbox = new QHBoxLayout();

    QVBoxLayout* vBox = new QVBoxLayout();
    menuA = new MainMenuListView(w, "Images");
    menuB = new MainMenuListView(w, "Videos");
    menuC = new MainMenuListView(w, "Devices");
    vBox->addWidget(menuA);
    vBox->addWidget(menuB);
    vBox->addWidget(menuC);
    vBox->setSpacing(0);
    hbox->addLayout(vBox);

    QPlainTextEdit* textEdit = new QPlainTextEdit(w);
    hbox->addWidget(textEdit);

    w->setLayout(hbox);
    setCentralWidget(w);

    move((QApplication::desktop()->screenGeometry().width() / 2) - (size().width() / 2),
         (QApplication::desktop()->screenGeometry().height() / 2) - (size().height() / 2));

}

MainWindow::~MainWindow() {}

Använd fall: provutgång

Här är en provutgång:

Staplade QListView-widgetar

Som du kan se ovan kan det vara användbart för att skapa staplade menyer. Observera att detta prov är trivialt. De två widgetarna har samma storlekskrav.



Modified text is an extract of the original Stack Overflow Documentation
Licensierat under CC BY-SA 3.0
Inte anslutet till Stack Overflow