Qt 小部件;如何创建类似 QT Creator 项目选择器的设计

Qt Widgets; how to create a design like QT Creator projects picker

我以为这会很容易,但现在我已经一周了,而且还很遥远。我正在尝试创建一个带有 "recently opened" 列表的欢迎屏幕。目标是让它设计得有点像 QT Creator 中的项目列表:

我认为我可以使用某种形式的列表小部件,但我还没有找到合适的。所以现在我开始尝试自己创建它。这是目前的结果:

我为此使用了以下代码:

QGridLayout *childLayout1= new QGridLayout();
QLabel *label1_1 = new QLabel("first label");
QLabel *label1_2 = new QLabel("Child first label");
childLayout1->addWidget(label1_1);
childLayout1->addWidget(label1_2);

QGridLayout *childLayout2= new QGridLayout();
QLabel *label2_1 = new QLabel("second label");
QLabel *label2_2 = new QLabel("Child second label");
childLayout2->addWidget(label2_1);
childLayout2->addWidget(label2_2);


QGridLayout *mainLayout = new QGridLayout();
mainLayout->addItem(childLayout1, 0, 0);
mainLayout->addItem(childLayout2, 1, 0);

ui->mainFrame->setLayout(mainLayout);

现在我迷路了。它看起来离 QT Creator 的列表选择器很远。事实上,它甚至无法使用。有人对我如何处理这个设计问题有任何指示吗?

一些休息创造了奇迹,我得到了一些现在看起来足够好的东西。希望这个回答以后能对大家有所帮助。

它使用放置在 QGridLayout 中的 QFrame。在 QGridLayout 上使用 setRowStretch 解决了问题中提到的对齐问题。使用的值可以调整,25 有点太多了。但我不完全确定它是如何工作的,所以我暂时保留它。

它还使用 eventFilter 来捕捉鼠标左键在框架上的点击。

在我的 mainwindow.h 文件下面:

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class QFrame;

class MainWindow : public QMainWindow
{
    Q_OBJECT

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

private:
    Ui::MainWindow *ui;
    QImage *img = new QImage(":/all/Folder-1.svg");
    QPixmap p = QPixmap::fromImage(*img);

    QFrame *CreateNewRow(int number, QString title, QString subtitle, QString mouseReleaseValue, int generalFontSize=18);

protected:
    bool eventFilter(QObject *obj, QEvent *event) override;
};
#endif // MAINWINDOW_H

还有我的 mainwindow.cpp 文件:

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QLabel>
#include <QGridLayout>
#include <QMouseEvent>
#include <QMessageBox>

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    QFrame *row1 = CreateNewRow(1, "First row", "First subtitle row", "row_1");
    QFrame *row2 = CreateNewRow(2, "Second row", "Second subtitle row", "row_2");

    QGridLayout *mainLayout = new QGridLayout();
    // All rows no stretch
    // Not sure about the magic numbers, but it works..
    mainLayout->setRowStretch(25, 25);
    mainLayout->addWidget(row1, 0, 0);
    mainLayout->addWidget(row2, 1, 0);

    ui->mainFrame->setLayout(mainLayout);
}

QFrame* MainWindow::CreateNewRow(int number, QString title, QString subtitle, QString mouseReleaseValue, int generalFontSize)
{
    QString styleFrame = QString("*:hover {background: #F6F6F6;}");
    QString styleNumber = QString("font-size: %1px; color: #8B8D8F;").arg(qRound(generalFontSize * 0.7));
    QString styleTitle = QString("font-size: %1px; color: #5CAA15;").arg(generalFontSize);
    QString styleSubtitle = QString("font-size: %1px; color: #8B8D8F;").arg(qRound(generalFontSize * 0.7));

    QFrame *frame = new QFrame();
    frame->setStyleSheet(styleFrame);
    frame->setCursor(Qt::PointingHandCursor);
    frame->installEventFilter(this);
    frame->setProperty("mouseReleaseValue", mouseReleaseValue);

    QLabel *imgDisplayLabel = new QLabel("");
    imgDisplayLabel->setPixmap(p.scaled(generalFontSize, generalFontSize, Qt::KeepAspectRatio));
    imgDisplayLabel->adjustSize();
    imgDisplayLabel->setContentsMargins(5, 0, 10, 0);

    QGridLayout *layout= new QGridLayout(frame);
    // All rows no stretch
    // Not sure about the magic numbers, but it works..
    layout->setColumnStretch(25, 25);

    QLabel *labelNumber = new QLabel(QString::number(number));
    QLabel *labelTitle = new QLabel(title);
    QLabel *labelSubtitle = new QLabel(subtitle);

    labelNumber->setStyleSheet(styleNumber);
    labelTitle->setStyleSheet(styleTitle);
    labelSubtitle->setStyleSheet(styleSubtitle);

    layout->addWidget(labelNumber, 0, 0);
    layout->addWidget(imgDisplayLabel, 0, 1, Qt::AlignVCenter);
    layout->addWidget(labelTitle, 0, 2);
    layout->addWidget(labelSubtitle, 1, 2);

    return frame;
}

bool MainWindow::eventFilter(QObject *obj, QEvent *event)
{
    if (event->type() == QEvent::MouseButtonRelease) {
        QMouseEvent* mouseEvent = static_cast<QMouseEvent*> (event);
        if (mouseEvent->button() == Qt::LeftButton) {
            QString prop = obj->property("mouseReleaseValue").toString();
            QMessageBox msgBox;
            msgBox.setText(QString("You have clicked an object with mouseReleaseValue: %1.").arg(prop));
            msgBox.exec();
            return true;
        }
    }
    // standard event processing
    return QObject::eventFilter(obj, event);
}

MainWindow::~MainWindow()
{
    delete ui;
}