Menu

Posts tagged with ‘krita’

Fixing Qt warning “QLayout: Attempting to add QLayout “” to QWidget “”, which already has a layout”

kinow @ Apr 02, 2017 12:01:03

If you ever started Krita 3.x in your command line, and had a look at the console output, you may noticed the following warning.

QLayout: Attempting to add QLayout “” to QWidget “”, which already has a layout

Krita recently announced the release of 3.1.3-alpha-2, and while testing I saw this warning and decided to investigate why this warning happens.

There was already a similar question posted on StackOverflow. And the best answer’s initial paragraph gave me a hint of what to look for.

When you assign a widget as the parent of a QLayout by passing it into the constructor, the layout is automatically set as the layout for that widget. In your code you are not only doing this, but explicitly calling setlayout(). This is no problem when when the widget passed is the same. If they are different you will get an error because Qt tries to assign the second layout to your widget which has already had a layout set.

So, somewhere in Krita code, there was a a QWidget being created, and layouts were being added to it more than once. To find where the issue was happening was quite easy. A breakpoint at main.cc where the application is initialized, then step through a few times, until the message appeared in the console.

Further investigation led me to the History docker (the one that shows undo steps) constructor.

    QVBoxLayout *vl = new QVBoxLayout(page); // layout being set to page
    m_undoView = new KisUndoView(this);
    vl->addWidget(m_undoView);
    QHBoxLayout *hl = new QHBoxLayout(page); // layout being set to page again
    hl->addSpacerItem(new QSpacerItem(10, 1,  QSizePolicy::Expanding, QSizePolicy::Fixed));
    m_bnConfigure = new QToolButton(page);
    m_bnConfigure->setIcon(KisIconUtils::loadIcon("configure"));
    connect(m_bnConfigure, SIGNAL(clicked(bool)), SLOT(configure()));
    hl->addWidget(m_bnConfigure);
    vl->addItem(hl);

    setWidget(page);
    setWindowTitle(i18n("Undo History"));

Here the QWidget created receives both QHBoxLayout and QVBoxLayout. Again, searching the Internet a little bit, then came across this post with a good example of a QWidget with QHBoxLayout and QVBoxLayout. Here’s what the constructor looks after the patch has been applied.

    QVBoxLayout *vl = new QVBoxLayout(page); // layout being set to page
    m_undoView = new KisUndoView(this);
    vl->addWidget(m_undoView);
    QHBoxLayout *hl = new QHBoxLayout();
    hl->addSpacerItem(new QSpacerItem(10, 1,  QSizePolicy::Expanding, QSizePolicy::Fixed));
    m_bnConfigure = new QToolButton(page);
    m_bnConfigure->setIcon(KisIconUtils::loadIcon("configure"));
    connect(m_bnConfigure, SIGNAL(clicked(bool)), SLOT(configure()));
    hl->addWidget(m_bnConfigure);
    vl->addItem(hl);
    vl->addLayout(hl); // horizontal layout added to the vertical layout

    setWidget(page);
    setWindowTitle(i18n("Undo History"));

That’s it. Learned something new in Qt. Not as important and useful as learning about signals and slots, but now I can focus on other warnings in the console output of Krita.

And you? Have you tested Krita 3.1.3 alpha already? What are you waiting for? :-)

♥ Open Source

Simulating less memory with ulimit

kinow @ Mar 26, 2017 11:14:03

These days I was trying to reproduce a bug in Krita where it would crash when a user copied group layers between windows. It appeared that the user was getting a segmentation fault due to the user’s computer running out of memory.

I could not reproduce the issue, but my computer has 16 GB. The first thing that came to my mind was to create a virtual machine with less memory to reproduce the issue. But I decided to spend some time looking for a simpler way of doing it.

Searching the web I found some suggestions that ulimit could work. After playing for a while with ulimit and htop, and verifying the amount of memory necessary to open two files in two windows in Krita, I came up with the following settings.

# 2550 mb in kb
ulimit -v 2550000

# 2 gb in kb
ulimit -m 2000000

# Confirm limits
ulimit -a

gdb $HOME/Development/cpp/workspace/krita_install/bin/krita

Then after copying a few layers from one window to another, I successfully reproduced the issue, and could include a backtrace in the Krita issue tracking system.

♥ Open Source

Contributing to Krita

kinow @ Jan 03, 2017 11:40:03

As I mentioned in the last post, I have been learning Qt and using C and C++ again. Since I used C and C++ more during university (about 10 years ago, phew), decided to read real code.

I used Photoshop, Illustrator, and Fireworks a lot when I was younger and had more time to spend drawing. But some time ago I switched to Inkscape for vector graphics, which I use at work for presentations. So it was only natural to try Krita now.

Since I was going to try Krita, I thought why not check out and build from source, and then in case I found any bugs, contribute back? Or maybe from time to time triage issues, find low hanging ones, and send a patch?

Well, turns out the Krita project has a great community, and it is super easy to send contributions. So far I submitted three patches, some were included in 3.x releases.

While the patches are rather small, they are suggestions on how to fix memory segmentation faults, or strange behaviours in the interface. For these issues, I had to learn more about Qt components, signals and emitting events, and, of course, work with pointers, arrays, Qt data structures, etc. In other words, lots of (geek) fun!

In other words, by contributing to Krita, I am not only helping the project and giving a little back to the community, but also refreshing my memory on C and C++, and slowly learning Qt - which is not very hard if you worked with Swing/AWT, Delphi, Visual Basic, Gtk, etc.

What are you waiting to contribute to Krita? The developers that maintain the project answer tickets and questions posted to reddit in a good time, and are extremely easy to work with.

Read more here how to build from source, and here on how to submit patches.

Happy hacking!

Debugging an application that freezes the X server

kinow @ Jan 02, 2017 00:39:03

Some time ago, I decided to start writing C++ again, and picked Krita for that. Krita is written in C++ and Qt. The bug I was working on involved a memory issue when changing the UI.

The problem was that this UI change would result in, not only Krita, but the whole X server freezing. My set up was basically Ubuntu 16.04.1 LTS, with Eclipse, Qt5, and the latest version of Krita checked out via git.

Initially I spent some time looking at the logs, tracing the binary, even downloaded some Qt utility tools to look at the events and what was happening with the application when it froze.

However, eventually I realized I was going to spend more time on this part of the issue, rather than on the memory bug. So decided to look for a work-around.

Thankfully someone else blogged about a similar issue and saved me a lot of time :-) Here’s how I did it, following the instructions in this blog post.

$ sudo apt-get install xnest -y
$ cd krita_install/
$ Xnest :10
$ twm -display :10
$ export DISPLAY=:10
$ ./krita

That’s it. You should have Krita running in a separate window, with Xnest, and within this window the twm window manager running. So when it freezes, at least you can still debug your application in Eclipse or whatever IDE you prefer.

Happy hacking!