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;
}
我以为这会很容易,但现在我已经一周了,而且还很遥远。我正在尝试创建一个带有 "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;
}