使用 GammaRay 在 QtWidgets 应用程序中找到某个功能的实现

2026-08-09T20:49:33+08:00

为了实践自由软件的自由 1 和自由 3,和/或为自由软件社区做出贡献,我们需要修改与某个功能相关的源代码,让软件做出不同的事情。然而,由于我们对某个项目并不熟悉,我们常常不知道需要修改的源代码在哪里。你可以试着运行 grep -R <some-user-facing-string> .,不过有时这并不会奏效(见上一篇文章)。在那种情况下,我们就需要一些高级的软件内省工具。对于使用 Qt 开发的软件,一个强大的工具是 GammaRay

要使用 GammaRay,你首先需要安装它。如果你想检查从发行版官方软件仓库安装的软件,那么也请从那里安装 GammaRay:

# apt install gammaray

如果你使用 kde-builder 开发 KDE 应用程序,请将以下几行添加到你的 ~/.config/kde-builder.yaml

project gammaray:
  repository: https://github.com/KDAB/GammaRay.git

然后把它构建到你的工作目录中:

$ kde-builder gammaray

要使用 GammaRay,你需要先让你想检查的应用程序运行起来。然后启动 GammaRay,并在列表中选择你的应用程序。

我们以在 Gwenview 中查找幻灯片逻辑为例。打开 Gwenview,然后打开一张图片,你会在菜单中看到 Start Slideshow 选项:

a screenshot of Gwenview

逐个浏览 Widgets 列表后,你会发现 0x13bda470 就是我们想要检查的菜单,其中包含 Start Slideshow 选项:

GammaRay QtWidgets introspection

而且我们会在 Connections 标签页中看到一个 toggle_slideshow QAction:

Connections

grep 会告诉我们这样的 QAction 位于哪里:

~/kde/src/gwenview$ grep -R toggle_slideshow
app/fullscreencontent.cpp:    addAction(QStringLiteral("toggle_slideshow"));
app/gwenviewui.rc:        <Action name="toggle_slideshow" />
app/mainwindow.cpp:        mToggleSlideShowAction = view->addAction(QStringLiteral("toggle_slideshow"), q, &MainWindow::toggleSlideShow);

在你常用的 IDE 中打开该项目,例如 Qt Creator,然后在 app/mainwindow.cpp 中搜索这个字符串。我们会在这里找到 toggle_slideshow

        mToggleSlideShowAction = view->addAction(QStringLiteral("toggle_slideshow"), q, &MainWindow::toggleSlideShow);
        q->updateSlideShowAction();
        connect(mSlideShow, &SlideShow::stateChanged, q, &MainWindow::updateSlideShowAction);

现在再搜索 toggleSlideShow,它会带我们找到这个函数:

void MainWindow::toggleSlideShow()
{
    if (d->mSlideShow->isRunning()) {
        d->mSlideShow->pause();
    } else {
        if (!d->mViewAction->isChecked()) {
            d->mViewAction->trigger();
        }
        if (!d->mFullScreenAction->isChecked()) {
            d->mFullScreenAction->trigger();
        }
        QList<QUrl> list;
        for (int pos = 0; pos < d->mDirModel->rowCount(); ++pos) {
            QModelIndex index = d->mDirModel->index(pos, 0);
            KFileItem item = d->mDirModel->itemForIndex(index);
            MimeTypeUtils::Kind kind = MimeTypeUtils::fileItemKind(item);
            switch (kind) {
            case MimeTypeUtils::KIND_SVG_IMAGE:
            case MimeTypeUtils::KIND_RASTER_IMAGE:
            case MimeTypeUtils::KIND_VIDEO:
                list << item.url();
                break;
            default:
                break;
            }
        }
        d->mSlideShow->start(list);
    }
    updateSlideShowAction();
}

继续搜索 mSlideShow,你会找到这里:

struct MainWindow::Private {
    ...
    SlideShow *mSlideShow = nullptr;
    ...
}

现在我们知道 d->mSlideShow 的类型是 SlideShow *。把鼠标悬停在 SlideShow 这个字符串上,会告诉我们它的类型来自 lib/slideshow.h

Qt Creator

现在打开 lib/slideshow.cpplib/slideshow.h,你就可以继续往下找了。

Tildeverse Banner Exchange