How to make QTextBrowser scale nicely within QVBoxLayout? - qt

I'd like to display a list of short html snippets in a scrollable list. Thus i place a QVboxLayout into a QScrollArea and add multiple QTextBrowsers:
#include <QApplication>
#include <QScrollArea>
#include <QTextBrowser>
#include <QVBoxLayout>
int main(int argc, char *argv[]) {
QApplication app(argc, argv);
QScrollArea scrollArea;
scrollArea.setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
scrollArea.setWidgetResizable(true);
QWidget *scrollWidget = new QWidget;
QVBoxLayout *layout = new QVBoxLayout;
for(int i=0;i<6;i++) {
QString text = "some <b>text</b> ";
for(int j=0;j<i;j++) text += text;
QTextBrowser *browser = new QTextBrowser();
QTextDocument *doc = new QTextDocument(browser);
doc->setHtml(text);
browser->setDocument(doc);
layout->addWidget(browser);
}
scrollWidget->setLayout(layout);
scrollArea.setWidget(scrollWidget);
scrollArea.show();
return app.exec();
}
My problem: The boxes all have the same size. I want them to be as big as necessary, but not bigger. How can i make the textbrowsers to take only as much space as they really need?

Ok, i found a solution derived from http://www.qtcentre.org/threads/39839-QTextBrowser-height-adjusted-to-content. Is there a simpler/mor elegant solution?
#include <QApplication>
#include <QScrollArea>
#include <QTextBrowser>
#include <QVBoxLayout>
#include <QGroupBox>
#include <QDebug>
#include <QShowEvent>
#include <QResizeEvent>
class MyBrowser : public QTextBrowser {
private:
QTextDocument *doc;
public:
MyBrowser(const QString &text, QWidget *parent = 0) : QTextBrowser(parent) {
doc = new QTextDocument(this);
doc->setHtml(text);
setDocument(doc);
}
void adjust() {
QMargins margins = contentsMargins();
int width = size().width() -
margins.left() - margins.right() - doc->documentMargin()*2;
doc->setPageSize(QSizeF(width,-1));
int height = doc->size().height() + margins.top() + margins.bottom();
setMaximumHeight(height);
setMinimumHeight(height);
}
void showEvent(QShowEvent *) {
adjust();
}
void resizeEvent(QResizeEvent *) {
adjust();
}
};
int main(int argc, char *argv[]) {
QApplication app(argc, argv);
QScrollArea scrollArea;
scrollArea.setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
scrollArea.setWidgetResizable(true);
QWidget *scrollWidget = new QWidget;
QVBoxLayout *layout = new QVBoxLayout;
for(int i=0;i<6;i++) {
QString text = "some <b>text</b> ";
for(int j=0;j<i;j++) text += text;
MyBrowser *browser = new MyBrowser(text, scrollWidget);
layout->addWidget(browser, 0, 0);
}
scrollWidget->setLayout(layout);
scrollArea.setWidget(scrollWidget);
scrollArea.show();
return app.exec();
}

Instead of doing
layout->addWidget(browser);
You should do:
layout->addWidget(browser, 0, 0);
This will tell QT not to stretch the widget according to its layout.

Related

Qt: How to link hand coded UI with UI builder?

I am looking for an easy way to link hand coded design to the UI for widgets applications in Qt. I plan to use the UI builder to easily adjust the layouts and obtain proper spacing, which I find hard to do without the UI builder.
I want to create a 3x3 grid of buttons for which I plan to use QVector< QVector<QPushButton*> > (I am not sure how I would do this in UI builder.)
Here is what I have tried, Why are the buttons not displayed even when I set the parent of each button to the widget ?
main.cpp
#include "window.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Window w;
w.show();
return a.exec();
}
window.h
#ifndef WINDOW_H
#define WINDOW_H
#include <QWidget>
#include <QPushButton>
namespace Ui {
class Window;
}
class Window : public QWidget
{
Q_OBJECT
public:
explicit Window(QWidget *parent = 0);
~Window();
private:
Ui::Window *ui;
static const int tiles = 50, height = 600, width = 500;
QVector< QVector<QPushButton*> > cells;
};
#endif // WINDOW_H
window.cpp
#include "window.h"
#include "ui_window.h"
Window::Window(QWidget *parent) :
QWidget(parent),
ui(new Ui::Window)
{
ui->setupUi(this);
this->resize(width, height);
int j = 0;
for(auto &row : cells)
{
int i = 0;
for(auto &col : row)
{
col = new QPushButton(this);
col->setGeometry(i, j, tiles, tiles);
i += tiles;
}
j += tiles;
}
}
Window::~Window()
{
delete ui;
for(auto &row : cells)
{
for(auto &col : row)
{
delete col;
}
}
}
Any help would be appreciated.
The vectors are empty, so you iterate over nothing. Instead of managing these manually, you could leverage the grid layout.
Alas, you're complicating things unnecessarily with all the manual memory management and geometry management. It's unnecessary. All you need to do is to add widgets to the layout you allude to. And even then, I don't see how relegating the layout to a .ui file helps you since there the layout must be empty. So yes: you can set spacings, but you won't see them until you run the code. So it seems like a pointless exercise, unless you have other elements you're not telling us about (why aren't you - you went so far already).
Below is a minimum example that simplifies it as much as practicable, but see this answer and the links therein for more idea.
// https://github.com/KubaO/stackoverflown/tree/master/questions/button-grid-43214317
#include <QtWidgets>
namespace Ui { class Window {
public:
// Approximate uic output
QGridLayout *layout;
void setupUi(QWidget * widget) {
layout = new QGridLayout(widget);
}
}; }
class Window : public QWidget
{
Q_OBJECT
Ui::Window ui;
QPushButton * buttonAt(int row, int column) {
auto item = ui.layout->itemAtPosition(row, column);
return item ? qobject_cast<QPushButton*>(item->widget()) : nullptr;
}
public:
explicit Window(QWidget *parent = {});
};
Window::Window(QWidget *parent) : QWidget(parent) {
ui.setupUi(this);
for (int i = 0; i < 5; ++i)
for (int j = 0; j < 6; ++j)
{
auto b = new QPushButton(QStringLiteral("%1,%2").arg(i).arg(j));
ui.layout->addWidget(b, i, j);
}
}
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Window w;
w.show();
return a.exec();
}
#include "main.moc"

Issue with Qt Toolbar extension button

I have to add a toolbar in Qt like the Windows file system explorer one under menu bar (I'm under Windows 7) , that means when the window width is reduced, icons which don't have enough place to be displayed are automatically hidden and put into a drop down list (which is displayed when clicking to an arrow which appears to the toolbar's right side). I first copy paste a code that I found to the web :
#include <QApplication>
#include <QAction>
#include <QMainWindow>
#include <QLineEdit>
#include <QToolBar>
#include <QHBoxLayout>
void initWindow(QMainWindow* w);
int main(int argc, char *argv[])
{
Q_INIT_RESOURCE(application);
QApplication app(argc, argv);
QMainWindow mainWin;
initWindow(&mainWin);
mainWin.show();
return app.exec();
}
void initWindow(QMainWindow* w)
{
QLineEdit* searchBar = new QLineEdit;
QAction* newAct = new QAction(QIcon(":/images/new.png"), "&New", w);
newAct->setShortcuts(QKeySequence::New);
QAction* openAct = new QAction(QIcon(":/images/open.png"), "&Open...", w);
openAct->setShortcuts(QKeySequence::Open);
QAction* saveAct = new QAction(QIcon(":/images/save.png"), "&Save", w);
saveAct->setShortcuts(QKeySequence::Save);
QAction* cutAct = new QAction(QIcon(":/images/cut.png"), "Cu&t", w);
cutAct->setShortcuts(QKeySequence::Cut);
QAction* copyAct = new QAction(QIcon(":/images/copy.png"), "&Copy", w);
copyAct->setShortcuts(QKeySequence::Copy);
QAction* pasteAct = new QAction(QIcon(":/images/paste.png"), "&Paste", w);
pasteAct->setShortcuts(QKeySequence::Paste);
QToolBar* fileToolBar = w->addToolBar("File");
fileToolBar->addAction(newAct);
fileToolBar->addAction(openAct);
fileToolBar->addAction(saveAct);
QToolBar* editToolBar = w->addToolBar("Edit");
editToolBar->addAction(cutAct);
editToolBar->addAction(copyAct);
editToolBar->addAction(pasteAct);
editToolBar->addWidget(searchBar);
}
... but the problem is that code works only for toolbars into a QMainWindow (and add by using QMainWindow::addToolbar() method). But into the code which I'm working for I have to do that into a QWidget, not a QWindow. So I created a horizontal layout, I added several widget into it (a QLineEdit and several QAction) and it works fine for QAction but not for QLineEdit : When I click to the arrow, all hidden QAction are visibles but not QLineEdit. Here is my code :
#include <QApplication>
#include <QtGui/QWindow>
#include <QToolbar>
#include <QVBoxLayout>
#include <QMainWindow>
#include <QPushButton>
#include <QAction>
#include <QIcon>
#include <QLineEdit>
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
QWidget* w = new QWidget;
QHBoxLayout* tb1 = new QHBoxLayout;
tb1->addWidget(new QPushButton("item11"));
tb1->addWidget(new QPushButton("item12"));
tb1->addWidget(new QPushButton("item13"));
tb1->addWidget(new QPushButton("item14"));
QHBoxLayout* spacerLayout = new QHBoxLayout;
spacerLayout->addSpacerItem(new QSpacerItem(50, 20, QSizePolicy::MinimumExpanding,QSizePolicy::Fixed) );
spacerLayout->setAlignment(Qt::AlignJustify);
QWidget* sep = new QWidget;
QRect rect = sep->geometry();
rect.setWidth(0);
sep->setGeometry(rect);
QToolBar* tb3 = new QToolBar;
QLineEdit* searchBar = new QLineEdit;
QAction* item31 = new QAction(QIcon(":/images/cut.png"), "cut");
QAction* item32 = new QAction(QIcon(":/images/copy.png"), "copy");
QAction* item33 = new QAction(QIcon(":/images/open.png"), "open");
QAction* item34 = new QAction(QIcon(":/images/paste.png"), "past");
QAction* item35 = new QAction(QIcon(":/images/save.png"), "save");
tb3->addWidget(sep);
tb3->addWidget(searchBar);
tb3->addAction(item31);
tb3->addAction(item32);
tb3->addAction(item33);
tb3->addAction(item34);
tb3->addAction(item35);
QVBoxLayout* mainLayout = new QVBoxLayout;
QHBoxLayout* topLayout = new QHBoxLayout;
topLayout->addLayout(tb1);
topLayout->addLayout(spacerLayout);
topLayout->addWidget(tb3);
QHBoxLayout* bottomLayout = new QHBoxLayout;
bottomLayout->addWidget(new QPushButton);
mainLayout->addLayout(topLayout);
mainLayout->addLayout(bottomLayout);
w->setLayout(mainLayout);
w->show();
return app.exec();
}
These are screenshots of the result with the 2nd solution : I first launch application :
http://img4.hostingpics.net/pics/224120tb1.jpg
When I reduce its width, widgets which are to the right side disapeared. Then I click to the arrow to display them into the drop down list and they are all displayed except the QLineEdit :
http://img4.hostingpics.net/pics/903380tb2.jpg
Is someone here knows what the problem is ? Thanks.
Regrettably, tool bars only function correctly when embedded in a QMainWindow. The good news is that you can use a QMainWindow as if it were a widget. You can parent it to another widget, and then it won't be a standalone window. I've done this, and it works well. I was creating the objects using Qt Designer, and I had to remove the QMainWindow menu bar because Designer creates that automatically.
It's not an intuitive thing to do, but it works just fine, and it's a fairly easy change. A well-written comment explaining why you did that would probably be welcomed by anyone else reading the code in the future...
Thank you for your answer, I tried to test with a QMainWindow but it completely messed up the layout on which I worked and as it's a complex window (a lot of people worked on it in the past) and I have to finish my work soon I preferred to try a new approach. So after some research on the web I found that it's possible to do that I want even if the toolbar is not into a QMainWindow, but I have to replace all QWidget's that I want to have into QToolBar by a class which derived of QWidgetAction's, and instantiate them into QWidgetAction::createWidget() method. So I did this code which works correctly :
main.cpp :
#include <QApplication>
#include <QtGui/QWindow>
#include <QToolbar>
#include <QVBoxLayout>
#include <QMainWindow>
#include <QPushButton>
#include <QAction>
#include <QIcon>
#include <QLineEdit>
#include <QSlider>
#include <QVariant>
#include <QCheckBox>
#include <QWidgetAction>
#include "QMyWidgetAction.h"
void test2(QApplication& app);
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
test2(app);
return app.exec();
}
void test2(QApplication& app)
{
QWidget* w = new QWidget;
QHBoxLayout* l1 = new QHBoxLayout;
l1->addWidget(new QPushButton("item11"));
l1->addWidget(new QPushButton("item12"));
l1->addWidget(new QPushButton("item13"));
l1->addWidget(new QPushButton("item14"));
QHBoxLayout* l2 = new QHBoxLayout;
l2->addSpacerItem(new QSpacerItem(50, 20, QSizePolicy::MinimumExpanding,QSizePolicy::Fixed) );
l2->setAlignment(Qt::AlignJustify);
QHBoxLayout* l3 = new QHBoxLayout;
QToolBar* tb = new QToolBar;
l3->addWidget(tb);
QAction* item31 = new QAction(QIcon(":/images/cut.png"), "cut");
QAction* item32 = new QAction(QIcon(":/images/copy.png"), "copy");
QAction* item33 = new QAction(QIcon(":/images/open.png"), "open");
QAction* item34 = new QAction(QIcon(":/images/paste.png"), "past");
QAction* item35 = new QAction(QIcon(":/images/save.png"), "save");
QLineEdit* searchBar = new QLineEdit;
QMyWidgetAction* widgetAction = new QMyWidgetAction(tb);
QLineEditAction* lineEditAction = new QLineEditAction(tb);
tb->addSeparator();
tb->addWidget(searchBar);
tb->addAction(item31);
tb->addAction(item32);
tb->addAction(item33);
tb->addAction(item34);
tb->addAction(item35);
tb->addAction(widgetAction);
tb->addAction(lineEditAction);
QVBoxLayout* mainLayout = new QVBoxLayout;
QHBoxLayout* topLayout = new QHBoxLayout;
topLayout->addLayout(l1);
topLayout->addLayout(l2);
topLayout->addLayout(l3);
QHBoxLayout* bottomLayout = new QHBoxLayout;
bottomLayout->addWidget(new QPushButton);
mainLayout->addLayout(topLayout);
mainLayout->addLayout(bottomLayout);
w->setLayout(mainLayout);
w->show();
}
QMyWidgetAction.h :
#ifndef QMAYAWIDGETACTION_H
#define QMAYAWIDGETACTION_H
#include <QObject>
#include <QWidget>
#include <QWidgetAction>
class QLineEdit;
class QMyWidgetAction : public QWidgetAction
{
Q_OBJECT
public:
QMyWidgetAction(QWidget* parent);
QWidget* createWidget(QWidget* parent);
};
class QLineEditAction : public QWidgetAction
{
Q_OBJECT
public:
QLineEditAction(QWidget* parent);
QWidget* createWidget(QWidget* parent);
protected slots:
virtual void searchTextChanged(const QString& text);
private:
QLineEdit* fWidget;
};
#endif // QMAYAWIDGETACTION_H
QMyWidgetAction.cpp :
#include <QApplication>
#include <QtGui/QWindow>
#include <QToolbar>
#include <QVBoxLayout>
#include <QMainWindow>
#include <QPushButton>
#include <QAction>
#include <QIcon>
#include <QLineEdit>
#include <QSlider>
#include <QVariant>
#include <QCheckBox>
#include <QWidgetAction>
#include "QMyWidgetAction.h"
QMyWidgetAction::QMyWidgetAction(QWidget* parent)
: QWidgetAction(parent)
{
}
QWidget* QMyWidgetAction::createWidget(QWidget* parent)
{
QPushButton* widget = new QPushButton("bouton", parent);
widget->setMinimumSize(100, 30);
return widget;
}
QLineEditAction::QLineEditAction(QWidget* parent)
: QWidgetAction(parent)
{
}
QWidget* QLineEditAction::createWidget(QWidget* parent)
{
fWidget = new QLineEdit(parent);
connect(fWidget, SIGNAL(textChanged(QString)), this, SLOT(searchTextChanged(QString)));
fWidget->setMinimumSize(100, 30);
return fWidget;
}
void QLineEditAction::searchTextChanged(const QString& text)
{
fWidget->setMinimumWidth(fWidget->minimumWidth() + 10);
}
So now here is what I get when I reduce the window width :
So the result is correct (and controls works, I tested them), but now I would like to know if it's possible to display the extension list horizontally instead of vertically ? (I mean "past" action at the right of "open" action, "save" action at the right of past action etc.) Thanks for your help.

How to avoid periodic flicker/drag effect during slideshow with QPropertyAnimation

QPropertyAnimation produces periodic flicker/drag effect during animation of longer duration of about 1 second or two. For small duration animation (about 500 ms or less) the QPropertyAnimation produces smooth animation without that specific flicker/drag effect. That flicker/drag like effect appears round about every 500ms. And i need to come across some solution as soon as possible. I have attached the minimal compilable example reproducing the problem. Please have a look and help.
I am using Qt5.5 in Windows10, i use both MinGW and Visual Studio 2013 compilers, Core i5 Laptop.
#include <QCoreApplication>
#include <QWidget>
#include <QVBoxLayout>
#include <QPushButton>
#include <QLabel>
#include <QPropertyAnimation>
#include <QApplication>
class Widget : public QWidget {
Q_OBJECT
public:
Widget(QWidget *parent = 0) : QWidget(parent) {
QVBoxLayout *l = new QVBoxLayout(this);
placeholder = new QWidget;
placeholder->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
l->addWidget(placeholder);
QPushButton *b = new QPushButton;
l->addWidget(b);
b->setText("click");
connect(b, SIGNAL(clicked()), this, SLOT(nextPage()));
current = 0;
}
public slots:
void nextPage() {
QWidget *newPage = new QLabel("page");
newPage->setAutoFillBackground(true);
QStringList c = QColor::colorNames();
QPalette p = newPage->palette();
p.setColor(QPalette::Window, QColor(c.at(qrand() % c.size())));
newPage->setPalette(p);
newPage->setParent(placeholder);
QPropertyAnimation *anim = new QPropertyAnimation(newPage, "geometry", newPage);
QRect start = placeholder->rect();
start.setTopLeft(start.topRight());
newPage->setGeometry(start);
anim->setStartValue(start);
anim->setEndValue(placeholder->rect());
anim->setDuration(4000);
anim->start();
if(current) {
QPropertyAnimation *anim = new QPropertyAnimation(current, "geometry", current);
anim->setStartValue(placeholder->rect());
QRect r = placeholder->rect();
r.translate(-r.width(), 0);
anim->setEndValue(r);
anim->setDuration(4000);
connect(anim, SIGNAL(finished()), current, SLOT(deleteLater()));
anim->start();
}
current = newPage;
current->show();
}
private:
QWidget *placeholder;
QWidget *current;
};
#include "main.moc"
int main(int argc, char **argv) {
QApplication app(argc, argv);
Widget w;
w.show();
return app.exec();
}

QListView with checkboxes for viewing of filesystem

It is necessary to list of directories by given path in QListView whith icons and checkboxes, then transmit names of marked folders to the program. For list directories i use code:
#include <QtGui/QApplication>
#include <QFileSystemModel>
#include <QListView>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QFileSystemModel model;
QListView listView;
listView.setModel(&model);
listView.setRootIndex(model.setRootPath("C:\\Program Files"));
listView.show();
return a.exec();
}
How to add checkboxes and transmit it after pushing button?
Thanks.
There's nothing you can do that would fit in just a few lines. You can either derive from QFileSystemModel and add a checkbox column, or create a proxy model that will do the same.
Note that you can use built-in selection mechanism to Ctrl-click/⌘-click to expand the selection to multiple items:
//main.cpp
#include <QApplication>
#include <QFileSystemModel>
#include <QGridLayout>
#include <QListView>
#include <QPushButton>
#include <QMessageBox>
class Win : public QWidget
{
Q_OBJECT
QListView * view;
QPushButton * button;
public:
Win(QAbstractItemModel * model, const QModelIndex & idx) :
view(new QListView(this)), button(new QPushButton("List Selection", this))
{
QGridLayout * lay = new QGridLayout;
lay->addWidget(view, 0, 0, 1, 2);
lay->addWidget(button, 1, 0);
setLayout(lay);
view->setSelectionMode(QAbstractItemView::MultiSelection);
view->setModel(model);
view->setRootIndex(idx);
connect(button, SIGNAL(clicked()), SLOT(showSelection()));
}
public slots:
void showSelection() {
QString str;
foreach (QModelIndex i, view->selectionModel()->selectedIndexes()) {
str.append(i.data().toString());
str.append("\n");
}
QMessageBox::information(this, "Selected items", str);
}
};
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QFileSystemModel model;
Win v(&model, model.setRootPath("/"));
v.show();
return a.exec();
}
#include "main.moc"

Why doesn't setPos() move the QGraphicsItems in the scene?

In the code below, I have three QGraphicsItems that are laid out by QGraphicsLinearLayout, which is set as layout to a QGraphicsWidget.
#include <QApplication>
#include <QBrush>
#include <QDebug>
#include <QGraphicsItem>
#include <QGraphicsLayoutItem>
#include <QGraphicsLinearLayout>
#include <QGraphicsRectItem>
#include <QGraphicsScene>
#include <QGraphicsView>
#include <QGraphicsWidget>
#include <QPen>
class MyShape : public QGraphicsRectItem, public QGraphicsLayoutItem {
public:
MyShape(void) {
setPen(QPen(QBrush(Qt::black), 1));
setBrush(QBrush(Qt::green));
setRect(0, 0, 20, 20);
}
virtual QSizeF sizeHint(Qt::SizeHint which,
const QSizeF& constraint = QSizeF()) const {
Q_UNUSED(which);
Q_UNUSED(constraint);
return boundingRect().size();
}
virtual void setGeometry(const QRectF& rect) {
setPos(rect.topLeft());
}
};
int main(int argc, char** argv) {
QApplication app(argc, argv);
QGraphicsScene scene;
MyShape* shape1 = new MyShape;
MyShape* shape2 = new MyShape;
MyShape* shape3 = new MyShape;
scene.addItem(shape1);
scene.addItem(shape2);
scene.addItem(shape3);
QGraphicsLinearLayout* layout = new QGraphicsLinearLayout;
layout->addItem(shape1);
layout->addItem(shape2);
layout->addItem(shape3);
QGraphicsWidget* container = new QGraphicsWidget;
container->setLayout(layout);
scene.addItem(container);
container->setPos(300, 300); // This doesn't appear to have any affect
// Item for indicating origin
QGraphicsRectItem* tmp = scene.addRect(0, 0, 2, 2, QPen(),
QBrush(Qt::green));
tmp->setPos(0, 0);
qDebug() << tmp->scenePos();
qDebug() << container->scenePos();
QGraphicsView view;
view.setScene(&scene);
view.centerOn(0, 0);
view.show();
return app.exec();
}
Then, I try to move the QGraphicsWidget within the scene by calling setPos(), but it doesn't appear to work (the QGraphicsItems remain in the same place). However, something appears to happen since the scrollbars change. It seems that the QGraphicsWidget moves, without taking the QGraphicsItems along with it.
Why?
EDIT:
By suggestion from DerManu, I changed the inheritance of MyShape to QGraphicsWidget, and with the following code, it works:
#include <QApplication>
#include <QBrush>
#include <QDebug>
#include <QGraphicsItem>
#include <QGraphicsLayoutItem>
#include <QGraphicsLinearLayout>
#include <QGraphicsRectItem>
#include <QGraphicsScene>
#include <QGraphicsView>
#include <QGraphicsWidget>
#include <QPen>
class MyShape : public QGraphicsWidget {
public:
MyShape(void) {
setMinimumSize(20, 20);
setMaximumSize(20, 20);
setPreferredSize(20, 20);
}
QRectF boundingRect(void) const {
QRectF box(0, 0, 22, 22);
box.translate(box.center() * -1);
return box;
}
void paint(QPainter* painter,
const QStyleOptionGraphicsItem* option,
QWidget* widget) {
Q_UNUSED(option);
Q_UNUSED(widget);
// Set box border appearance
painter->setPen(QPen(Qt::black, 1));
// Set box background appearance
painter->setBrush(QBrush(Qt::green));
QRectF box(0, 0, 20, 20);
box.translate(box.center() * -1);
painter->drawRect(box);
}
};
int main(int argc, char** argv) {
QApplication app(argc, argv);
QGraphicsScene scene;
MyShape* shape1 = new MyShape;
MyShape* shape2 = new MyShape;
MyShape* shape3 = new MyShape;
scene.addItem(shape1);
scene.addItem(shape2);
scene.addItem(shape3);
QGraphicsLinearLayout* layout = new QGraphicsLinearLayout(Qt::Vertical);
layout->addItem(shape1);
layout->addItem(shape2);
layout->addItem(shape3);
QGraphicsWidget* container = new QGraphicsWidget;
container->setLayout(layout);
scene.addItem(container);
container->setPos(200, 200); // This doesn't appear to have any affect
scene.setSceneRect(-300, -300, 600, 600);
// Item for indicating origin
QGraphicsRectItem* tmp = scene.addRect(0, 0, 2, 2, QPen(),
QBrush(Qt::green));
tmp->setPos(0, 0);
qDebug() << tmp->scenePos();
qDebug() << container->scenePos();
QGraphicsView view;
view.setScene(&scene);
view.centerOn(0, 0);
view.show();
return app.exec();
}
So what is it that QGraphicsWidget provides that I missed in the original code such that using setPos on the container item correctly moves the position of the MyShape items?

Resources