Skip to content

Thursday, 6 February 2025

Model/View Drag and Drop in Qt - Part 1

This blog series is all about implementing drag-and-drop in the Qt model/view framework. In addition to complete code examples, you'll find checklists that you can go through to make sure that you did not forget anything in your own implementation, when something isn't working as expected.

At first, we are going to look at Drag and Drop within a single view, to change the order of the items. The view can be a list, a table or a tree, there are very little differences in what you have to do.

part1-table-step1

Moving a row in a tableview, step 1

part1-table-step2

Moving a row in a tableview, step 2

part1-table-step3

Moving a row in a tableview, step 3

The main question, however, is whether you are using QListView/QTableView/QTreeView on top of a custom item model, or QListWidget/QTableWidget/QTreeWidget with items in them. Let's explore each one in turn.

With Model/View separation

The code being discussed here is extracted from the example. That example features a flat model, while this example features a tree model. The checklist is the same for these two cases.

Setting up the view

☑ Call view->setDragDropMode(QAbstractItemView::InternalMove) to enable the mode where only moving within the same view is allowed

☑ When using QTableView, call view->setDragDropOverwriteMode(false) so that it inserts rows instead of replacing cells (the default is false for the other views anyway)

Adding drag-n-drop support to the model

part1-list

Reorderable ListView

part1-table

Reorderable TableView

For a model being used in QListView or QTableView, all you need is something like this:

class CountryModel : public QAbstractTableModel
{
    ~~~
    Qt::ItemFlags flags(const QModelIndex &index) const override
    {
        if (!index.isValid())
            return Qt::ItemIsDropEnabled; // allow dropping between items
        return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsDragEnabled;
    }

    // the default is "copy only", change it
    Qt::DropActions supportedDropActions() const override { return Qt::MoveAction; }

    // the default is "return supportedDropActions()", let's be explicit
    Qt::DropActions supportedDragActions() const override { return Qt::MoveAction; }

    QStringList mimeTypes() const override { return {QString::fromLatin1(s_mimeType)}; }

    bool moveRows(const QModelIndex &sourceParent, int sourceRow, int count, const QModelIndex &destinationParent, int destinationChild) override; // see below
};

The checklist for the changes you need to make in your model is therefore the following:

☑ Reimplement flags()
For a valid index, add Qt::ItemIsDragEnabled and make sure Qt::ItemIsDropEnabled is NOT set (except for tree models where we need to drop onto items in order to insert a first child). \

☑ Reimplement mimeTypes() and make up a name for the mimetype (usually starting with application/x-)

☑ Reimplement supportedDragActions() to return Qt::MoveAction

☑ Reimplement supportedDropActions() to return Qt::MoveAction

☑ Reimplement moveRows()

Note that this approach is only valid when using QListView or, assuming Qt >= 6.8.0, QTableView - see the following sections for details.

In a model that encapsulates a QVector called m_data, the implementation of moveRows can look like this:

bool CountryModel::moveRows(const QModelIndex &sourceParent, int sourceRow, int count, const QModelIndex &destinationParent, int destinationChild)
{
    if (!beginMoveRows(sourceParent, sourceRow, sourceRow + count - 1, destinationParent, destinationChild))
        return false; // invalid move, e.g. no-op (move row 2 to row 2 or to row 3)

    for (int i = 0; i < count; ++i) {
        m_data.move(sourceRow + i, destinationChild + (sourceRow > destinationChild ? 0 : -1));
    }

    endMoveRows();
    return true;
}

QTreeView does not call moveRows

part1-tree

Reorderable treeview

part1-treemodel

Reorderable treeview with a tree model

QTreeView does not (yet?) call moveRows in the model, so you need to:

☑ Reimplement mimeData() to encode row numbers for flat models, and node pointers for tree models

☑ Reimplement dropMimeData() to implement the move and return false (meaning: all done)

Note that this means a move is in fact an insertion and a deletion, so the selection isn't automatically updated to point to the moved row(s).

QTableView in Qt < 6.8.0

I implemented moving of rows in QTableView itself for Qt 6.8.0, so that moving rows in a table view is simpler to implement (one method instead of two), more efficient, and so that selection is updated. If you're not yet using Qt >= 6.8.0 then you'll have to reimplement mimeData() and dropMimeData() in your model, as per the previous section.

This concludes the section on how to implement a reorderable view using a separate model class.

Using item widgets

The alternative to model/view separation is the use of the item widgets (QListWidget, QTableWidget or QTreeWidget) which you populate directly by creating items.

part1-listwidget

Reorderable QListWidget

part1-tablewidget

Reorderable QTableWidget

part1-treewidget

Reorderable QTreeWidget

Here's what you need to do to allow users to reorder those items.

Example code can be found following this link.

Reorderable QListWidget

☑ Call listWidget->setDragDropMode(QAbstractItemView::InternalMove) to enable the mode where only moving within the same view is allowed

For a QListWidget, this is all you need. That was easy!

Reorderable QTableWidget

When using QTableWidget:

☑ Call tableWidget->setDragDropMode(QAbstractItemView::InternalMove)

☑ Call tableWidget->setDragDropOverwriteMode(false) so that it inserts rows instead of replacing cells

☑ Call item->setFlags(item->flags() & ~Qt::ItemIsDropEnabled); on each item, to disable dropping onto items

Note: Before Qt 6.8.0, QTableWidget did not really support moving rows. It would instead move data into cells (like Excel). The example code shows a workaround, but since it calls code that inserts a row and deletes the old one, header data is lost in the process. My changes in Qt 6.8.0 implement support for moving rows in QTableWidget's internal model, so it's all fixed there. If you really need this feature in older versions of Qt, consider switching to QTableView.

Reorderable QTreeWidget

When using QTreeWidget:

☑ Call tableWidget->setDragDropMode(QAbstractItemView::InternalMove)

☑ Call item->setFlags(item->flags() & ~Qt::ItemIsDropEnabled); on each item, to disable dropping onto items

Conclusion about reorderable item widgets

Of course, you'll also need to iterate over the items at the end to grab the new order, like the example code does. As usual, item widgets lead to less code to write, but the runtime performance is worse than when using model/view separation. So, only use item widgets when the number of items is small (and you don't need proxy models).

Improvements to Qt

While writing and testing these code examples, I improved the following things in Qt 6.8:

  • QTBUG-13873 / QTBUG-101475 - QTableView: implement moving rows by drag-n-drop
  • QTBUG-69807 - Implement QTableModel::moveRows
  • QTBUG-130045 - QTableView: fix dropping between items when precisely on the cell border
  • QTBUG-1656 - Implement full-row drop indicator when the selection behavior is SelectRows

Conclusion

I hope this checklist will be useful when you have to implement your own reordering of items in a model or an item-widget. Please post a comment if anything appears to be incorrect or missing.

In the next blog post of this series, you will learn how to move (or even copy) items from one view to another.

The post Model/View Drag and Drop in Qt - Part 1 appeared first on KDAB.

Glaxnimate 0.6.0 Beta has finally been released for testing!

It has been a while since the last release of Glaxnimate, but in the background we worked hard to make this first release under the KDE umbrella happen!

Please help us testing and report any issue you may encounter on https://bugs.kde.org/enter_bug.cgi?product=glaxnimate

Glaxnimate joins KDE

The Glaxnimate team is proud to announce Glaxnimate is now part of KDE. Glaxnimate benefits from the shared KDE build and distribution infrastructure, the collective knowledge of the community and libraries such as KDE Frameworks. This way the developers can spend more time on the code to fix bugs and develop new features for you!

Changes

Editing

  • The rotation handle now preserves rotation direction and multiple full rotations
  • Alt + click on keyframes cycles between built-in easing curves
  • Alt + click on bezier points cycles between tangent symmetry modes (Ctrl+click still works)
  • Changing a bezier point from corner to smooth will add tangents if they are missing
  • The import image dialog now allows importing multiple images at once

I/O

  • Added support for SVG text-anchor

User Interface

  • Middle mouse drag now pans the timeline
  • There is an icon on the timeline to quickly toggle keyframes
  • Buttons to jump to the next/previous keyframe in the timeline
  • Improved LottieFiles import dialog
  • Improved autosave recovery process
  • Script console now supports basic autocompletion

Scripting

  • Exposed method to add new compositions

Misc

  • Switched to an even/odd version numbering scheme
  • Integration with KDE Frameworks

Bug Fixes

  • Fixed keyframe context menu showing the wrong "after" transition
  • When drawing bezier points that don't have tangents are correctly marked as corner
  • The play button now resumes from the current frame rather than resetting to the start
  • Fixed saving custom templates
  • Toggling visibility / lock of a layer by clicking on its icon now adds an undo/redo action
  • Fixed LottieFiles import
  • Fixed dropping file as object
  • Fixed closing compositions from the tab bar
  • Fixed loading colors from older lotties
  • Shape modifiers marked as not visible are now correctly ignored
  • Fixed rendering of round corners modifier
  • Fixed "New Composition" action creating an invisible layer
  • Fixed repeater opacity not being applied correctly
  • Improved handling of repeater with stroke
  • Fixed SVG animation export
  • Fixed animated raster plugin I/O

How to get it

Note that this is a beta release. Most Linux distributions do not package unstable releases.

We recommend to test this release with one of the binaries we provide:

Packager Section

The source code tarball are available from the KDE servers:

URL: https://download.kde.org/unstable/glaxnimate/0.5.80

Source: glaxnimate-0.5.80.tar.xz

Signed by: 97B71AA02D63EA6C5C44C23B962AC48EF0501F0B Julius Künzel julius.kuenzel@kde.org

Tuesday, 4 February 2025

From 6th to 10th of September 2024, part of the Kdenlive Team was in Germany to attend the annual KDE convention Akademy and used that opportunity of being together at the same location to have a sprint. It was good to meet face to face and to sit down and tackle some issues together. One of the topic discussed was improving our communication towards users, so here is a much needed update on the status of our fundraiser! This post should have been published a few months earlier but there were so much things happening around Kdenlive that it was hard to follow, so sorry for the delay!

It’s been a bit more than 2 years since we launched our very successful fundraiser. This allowed us to fund some much wanted features, and as a side goal, allowed me to spend more time on Kdenlive. Thanks to your donations, I will be able to dedicate two days per week to Kdenlive instead of one. Note that this only sponsors part of my work as I spend much more time to Kdenlive, but hopefully this will relieve some stress and I will have a healthier weekly rhythm.

During this time, there were around 1,900 commits to the Kdenlive repository, meaning about 3.8 commits per day! We didn’t take that much vacation, did we? Also worth noting is that we handled the port to Qt6 during that time, which was a big task and took a lot of effort.

So now for the status of the fundraiser, here is what has been done so far and what is left. All major things were implemented in the 24.12 release so that we can move on to our next goals soon.

Timeline Nesting

merged in 23.04

This was by far the biggest update since 2019, and can now be enjoyed by all (we recommend using the upcoming 24.12.2 version for the best experience). What remains for this task is to do some code cleanup that will be done in the 24.12 cycle. On a side note, the feature was merged too early and caused some annoying instabilities that are now solved. And I promise we are working to improve our development processes.

Improving the effects workflow

Several changes were made to improve the user experience and make our effects more powerful.

Group effects

merged in 24.05

Ability to control the parameters affecting all effects within the group.

Built-in effects

merged in 24.12

The effects panel gives direct access to effect parameters, allowing to quickly and easily adjust them.

More Easing Modes

merged in 24.02

In addition to the existing easing modes (linear, smooth, and constant), we’ve added several new options like: Cubic In/Out, Exponential In/Out, Circular In/Out, Elastic In/Out, and Bounce In/Out for transitions and effects.

Transform effect improvements

The Transform effect now has a monitor grid to easily align clips – merged in 24.12

Added ability to directly select clips from the monitor overlay – merged in 24.08

Redesigned effects interface

merged in 24.12

The Effect Stack redesign enhances usability with clearer organization of keyframeable and non-keyframeable parameters, improved layout consistency, more compact and clean.

Help button

merged in 24.12

Added a contextual help button in the effect / transition stack which redirects to the effect’s documentation on our fantastic documentation website.

Performance boost

Performance improvements is an always running task, but among some of the recent changes you will find:

  • Spacer tool boost – merged in 24.05, the Spacer tool that was previously very laggy when moving more than 10 clips was optimized to allow almost instant move
  • Improve speed for audio or video only rendering – merged in 24.08, a small improvement in the way the rendering is passed to MLT means slightly faster render times for the timeline preview
  • Improve support for hardware encoders – cleanup and improve the detection of the GPU used for timeline preview and proxy clips – merged in 23.08
  • Optimize parts of the timeline qml code – merged in 24.05, we now better handle out of view items

But wait, there’s more!

Thanks to your support we managed to achieve more than planned. We worked in improving our automated testing as well as hired third party developers for extra features.

Regression Testing

One thing we wanted for a long time was a way to automatically check for rendering regressions. We are now entering the final phase of this automated tests and it will soon be run automatically. Hopefully this will make future releases more stable and avoid some of the issues we had in the last years!

Audio Waveform Upgrade

merged for 25.04

The next major release of Kdenlive brings a 300% performance boost for generating audio thumbnails, along with higher-resolution waveforms for greater precision and a refactored sampling method that accurately renders the audio signal. This work was done by Étienne Paul André, check out the in depth details about thew work done here.

OpenTimelineIO Integration

expected in 25.08

Darby Jonhston is working on implementing a native C++ OpenTimelineIO integration to allow importing and exporting project files to/from other applications implementing this open standard. This has many advantages over the currently existing but very broken Python adapter based OTIO integration.

Export features:

  • Export a timeline with multiple tracks and clips. (working)
  • Support for markers and guides. (working)
  • Support for transitions. (not started)

Import features:

  • Import a timeline with multiple tracks and clips. (working)
  • Support for markers and guides. (working)
  • Support for transitions. (not started)

What’s next

During our sprint in Germany, we also updated our roadmap so that it better reflects the current status of our development and goals. We have something big planned for this year so stay tuned.

On behalf of the team, we would like to thank you all for your support that helps make Kdenlive better every day!

Monday, 3 February 2025

KStars v3.7.5 is released on 2025.02.03 for Windows, MacOS & Linux. It's a bi-monthly bug-fix release with a couple of exciting features. Here are the release notes organized by developer.

Jasem Mutlaq

  • Added dome slit visualization on sky map. Specify the Dome Measurement parameters in the INDI Dome driver to see a live dome slit overlay in the Sky Map.

  • Implemented generic DBus methods for KStars options
  • Added SchedulerSleeping event
  • Added mutex protection for multi-threaded resources
  • Enhanced scheduler loading and settings management
  • Improved filter manager operations
  • Fixed video subframing. Up to 50x improvement in subframed video feeds.
  • Fixed multiple profile editor issues
  • Added VSCode development setup support

Hy Murveit

  • Fixed DMS delta angle calculation
  • Added mandatory settle to PAA
  • Improved imaging planner stability


  • Fixed pierside placeholder directory usage
  • Added START_AT scheduler test
  • Fixed Abell planetary nebula lookup
  • Enhanced PAA adjustment estimation

Wolfgang Reissenberger

  • Implemented video sequence capture. Preliminary support for capturing Video files as regular sequences in the Capture module. Great news for EAA.

  • Fixed focus options
  • Improved remote directory handling
  • Fixed flats with wall position
  • Enhanced filter wheel integration

John Evans

  • Enabled focuser controls when camera disconnected
  • Improved focus measure framing
  • Fixed focus advisor code warnings
  • Updated aberration inspector functionality

Toni Schriber

  • Fixed overshooting cosine in CachingDms calculation
  • Implemented calibration reuse after rotation. Guide calibration data can now be re-used between sessions after rotation.

Ben Cooksley

  • Removed CMake trace/debug logs from CI runs

György Balló

  • Set window icon

Oliver Kellogg

  • Fixed typo in FITS Viewer configuration

Akarsh Simha

  • Fixed right-click popup menu on deep stars

Technical Highlights

  • Improved capture sequence stability: Set 5-minute timeout for transient operations (dome motion, mount parking/unparking, dust cap operations, focusing, filter wheel changes) to prevent indefinite sequence stalling.
  • Improved mount rotation processing
  • Enhanced scheduler loading mechanism
  • Added mutex protection for multi-threaded resources
  • Improved capture operation timeout handling

Sunday, 2 February 2025

A new Craft cache has just been published. The update is already available for KDE's CD, CI (Windows/Android) will follow in the next days.

Please note that this only applies to the Qt6 cache. The Qt5 cache is in LTS mode since April 2024 and does not recieve major updates anymore. We highly recommend to port your Qt5 app packaged by Craft to Qt6 as soon as possible!

Changes (highlights)

General

We added CI for flake8, isort and black with the help of tox (which makes it easy to run them locally too) to all Craft repositories. To be able to do so we did a lot of best pratice cleanup beforehand like eg. removing star imports.

Craft Core

  • Drop support for MSVC 2017
  • Introduced a CraftBool helper. This allows handy things like self.subinfo.options.dynamic.withMyLib.asOnOff instead of 'ON' if self.subinfo.options.dynamic.withMyLib else 'OFF'
  • Fix: let the Meson build system respect the buildStatic option
  • Handle --enable-static --enable-shared in AutoToolsPackageBase instead of in every single blueprint
  • Python packages (Linux and Windows MSVC; macOS is work in progress):
    • Build them ourself instead of using the pre-build binaries from pypi.org
    • Use proper staging
    • Allow to deploy/package them
  • Properly set Craft env when branch is switched (eg. with Craft Master in CI)

Blueprints

  • libjpeg-turbo 3.0.3
  • Multiple fixes for build of shared vs. static libs
  • libvpx 1.15.0
  • Add minGW 14.2 (not the default yet!)
  • 7z 24.09
  • KShimgen 0.6.1
  • linuxdeploy-plugin-qt 2.0.0-alpha-1-20250119
  • qtkeychain 0.15.0

About KDE Craft

KDE Craft is an open source meta-build system and package manager. It manages dependencies and builds libraries and applications from source on Windows, macOS, Linux, FreeBSD and Android.

Learn more on https://community.kde.org/Craft or join the Matrix room #kde-craft:kde.org

Saturday, 1 February 2025

The Linux App Summit is a project we KDE created, together with GNOME and some other parties. We wanted a physical space where to discuss our platform to different stakeholders.

We have seen lots of progress since 2019. From a KDE perspective, we see our flatpaks and snaps. This adoption brings all sorts of users to our software that otherwise wouldn’t have been able to.

From the other side of the equation, linux distros have been evolving like ever. We have seen a myriad of distributions using technologies that we would have never dreamed of. And we can find them both on consumer and development devices. Even KDE Linux and GNOME OS are looking into tightening the other end of that software distribution loop.

Now, it’s time to take things even further.

This year we will have LAS 2025 in Tirana. Consider participating in LAS 2025! How you ask?

  • Join us! It’s free to attend and, dare I say, we are lovely people.
  • Send a talk! You can come and talk us about how you are helping linux apps be a reality or what kind of problems you found with your app and how you solved them. Here you can find some more ideas.
  • Sponsor! Does your organisation take part in the linux ecosystem? Take part in it!

You can follow LAS updates on the Attendees chat or here @LAS@floss.social on Mastodon.

Thursday, 30 January 2025

Wednesday, 29 January 2025

gcompris 25.0

Today we are releasing GCompris version 25.0.

As you can see, we are now basing the major version number on the release year. This makes sense as we are doing one major version per year. It is also a good occasion to do it now to celebrate the 25 years of GCompris.

This version adds translation for one more language: Sanskrit.

This new version contains 195 activities, including 5 new ones:

  • "Sketch" is an activity for drawing freely with multiple tools to let children explore their creativity.
  • "Calculate with ten's complement" is the continuation of the existing ten's complement activities. This one helps the children to swap the numbers to easily compute a sum.
  • "Vertical addition" is an activity to write an addition and solve it.
  • "Vertical subtraction", is similar to the addition activity but for subtraction with the borrowing by regrouping method.
  • "Vertical subtraction (compensation)", is similar to the subtraction one with the borrowing by compensation method.

It contains bug fixes and graphics improvements on multiple activities.

With the help of teachers, we rewrote a big part of the activities description to be clearer.

When we switch language in the menu, the new language is now applied directly, without having to restart GCompris.

On the technical side, it is also the first release using Qt6.

We have also set the graphical renderer to direct3d11 by default on Windows.

It is fully translated in the following languages:

  • Arabic
  • Bulgarian
  • Breton
  • Catalan
  • Catalan (Valencian)
  • Greek
  • Spanish
  • Basque
  • French
  • Galician
  • Croatian
  • Hungarian
  • Italian
  • Latvian
  • Malayalam
  • Dutch
  • Polish
  • Brazilian Portuguese
  • Romanian
  • Sanskrit
  • Slovenian
  • Swedish
  • Turkish
  • Ukrainian

It is also partially translated in the following languages:

  • Azerbaijani (90%)
  • Belarusian (86%)
  • Czech (98%)
  • German (88%)
  • UK English (99%)
  • Esperanto (99%)
  • Estonian (88%)
  • Finnish (91%)
  • Hebrew (96%)
  • Indonesian (93%)
  • Georgian (85%)
  • Lithuanian (92%)
  • Macedonian (83%)
  • Norwegian Nynorsk (94%)
  • Portuguese (89%)
  • Russian (92%)
  • Slovak (82%)
  • Albanian (98%)
  • Swahili (92%)
  • Chinese Traditional (88%)

You can find packages of this new version for GNU/Linux, Windows, Android and Raspberry Pi on the download page. This update will also be available soon in the Android Play store, the F-Droid repository and the Windows store.

Thank you all,
Timothée & Johnny

Tuesday, 28 January 2025

tldr; save the date for our QtCS25, May 7-8 in Munich.
Stay tuned for more information.

Sunday, 26 January 2025

Project Description

In SoK 2025, I will be working on adding Pallanguzhi, a traditional Indian Mancala variant, into the Mankala Engine. Collaborating with Srisharan V S, my focus includes two key goals:

  1. Developing a computerized opponent to enhance player engagement and ensure a seamless gameplay experience.
  2. Creating a Text-Based User Interface (TUI) for gameplay.

What I Did This Week

The first step in my journey was setting up the Mankala Engine repository. I forked the repository to my local system, successfully built it, and resolved some warnings during the build process. Afterward, I delved into the codebase, analyzing the existing algorithms and understanding how they work for other Mancala variants.

Research on Implementing a Computerized Opponent

To create a robust computerized opponent for Pallanguzhi, I began researching potential algorithms that could best fit the game mechanics. Here are the three techniques I explored.

1. Reinforcement Learning

Reinforcement Learning (RL) is an exciting approach where an agent learns optimal strategies by interacting with the environment and improving over time. For Pallanguzhi, RL could enable the computerized opponent to adapt and improve its gameplay dynamically. However, as I am new to RL, implementing and training models for this variant will take some time and effort. Despite its challenges, RL remains a promising option for advanced gameplay enhancement.

2. Monte Carlo Tree Search (MCTS)

MCTS is a powerful algorithm widely used for decision-making in games. It works by simulating potential moves to build a decision tree and then selecting the best move based on statistical evaluation. For Pallanguzhi, MCTS could efficiently explore the vast game state space and make informed decisions. By carefully tuning the number of simulations and exploration parameters, this algorithm can provide a balanced and competitive computerized opponent.

3. Alpha-Beta Pruning with Iterative Deepening

Alpha-Beta Pruning with Iterative Deepening is a highly effective technique for optimizing decision trees by eliminating unnecessary branches. This method is already implemented in the Mancala Engine for other variants and has proven its efficiency. Leveraging this existing implementation for Pallanguzhi will allow us to quickly develop a working version of the game with a competent computerized opponent.

Conclusion for Now

The immediate plan is to integrate the Pallanguzhi variant into the existing Alpha-Beta Pruning implementation. This ensures we have a functional version of the game ready for any further work. Once the TUI implementation is complete, I plan to revisit Reinforcement Learning for Pallanguzhi. Working with RL models and training them is a learning-intensive process, and I am excited to gain experience in this area. Even if RL proves too challenging, we will still have a polished Pallanguzhi variant running on the existing algorithm.

What’s Next

Next week, I will work on adding the longer version of Pallanguzhi, which consists of multiple rounds, while Srisharan V S focuses on completing the shorter version. Together, we aim to make significant progress toward integrating and refining this traditional game within the Mankala Engine.

Stay tuned for updates!