對於標準 QWidget,透過 QLayout、QBoxLayout、QHBoxLayout 嵌套即可輕鬆完成漂亮佈局。但自定義控件卻讓人糾結:QGraphicsLayoutItem、QGraphicsLayout 無法直接添加自定義控件,只有 QGraphicsLinearLayout 的 addItem 可添加 QGraphicsLayoutItem 類型元素。透過繼承關係可見端倪:

解決方案:利用 QGraphicsWidget 在場景中間接添加控件,無需向 scene 逐個添加,只需將含佈局的 widget 一次加入 scene。
QGraphicsLinearLayout *linearLayout = new QGraphicsLinearLayout(Qt::Vertical);
QGraphicsWidget *widget = new QGraphicsWidget;
linearLayout->addItem(linkLabel);
linearLayout->addItem(appLabel);
widget->setLayout(linearLayout);
scene->addItem(widget);
但此法存在問題:垂直佈局時,系統自動對齊寬度,導致下方控件被拉伸(見錯誤圖)。

修正:為後續控件設定最大尺寸 appLabel->setMaximumSize(rectApp.width(), rectApp.height()); 即可正常顯示。

#include
#include
#include "showlabel.h"
#include "clickhandler.h"
int main(int argc, char *argv[]) {
QApplication app(argc, argv);
QGraphicsScene *scene = new QGraphicsScene;
QGraphicsView *view = new QGraphicsView(scene);
ShowLabel *linkLabel = new ShowLabel("www.hao123.com");
QFont linkFont("Arial", 20, QFont::Bold, true);
linkLabel->setFont(linkFont);
linkLabel->setUnderline(true);
QColor linkColor(255, 0, 0);
linkLabel->setColor(linkColor);
ShowLabel *appLabel = new ShowLabel("open app");
QFont appFont("times", 20, QFont::Bold, true);
appLabel->setFont(appFont);
appLabel->setUnderline(true);
QColor appColor(0, 255, 0);
appLabel->setColor(appColor);
linkLabel->setPreferredSize(rectLink.width(), rectLink.height());
ClickHandler *clickHandler = new ClickHandler(view);
QObject::connect(linkLabel, SIGNAL(clicked()), clickHandler, SLOT(on_linkOpen()));
QObject::connect(appLabel, SIGNAL(clicked()), clickHandler, SLOT(on_messageBox()));
scene->setSceneRect(0, 0, 300, 300);
QGraphicsLinearLayout *linearLayout = new QGraphicsLinearLayout(Qt::Vertical);
QGraphicsWidget *widget = new QGraphicsWidget;
linearLayout->addItem(linkLabel);
linearLayout->addItem(appLabel);
widget->setLayout(linearLayout);
scene->addItem(widget);
view->resize(300, 300);
view->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
view->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
view->setWindowTitle(QObject::tr("My hao123 Label"));
view->show();
return app.exec();
}
(完整代碼見原文,含自定義標籤繪製、滑鼠事件、點擊信號槽處理等核心邏輯)
本文出自「賣萌程序員」博客,轉載請保留出處:https://7677869.blog.51cto.com/7667869/1264729