<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>Qt on Rebel Zhang 的博客</title>
        <link>https://rebel1725.codeberg.page/blog/zh/tags/qt/</link>
        <description>Recent content in Qt on Rebel Zhang 的博客</description>
        <generator>Hugo -- gohugo.io</generator>
        <language>zh-CN</language>
        <managingEditor>rebel1725@tilde.club (Rebel Zhang)</managingEditor>
        <webMaster>rebel1725@tilde.club (Rebel Zhang)</webMaster>
        <lastBuildDate>Sun, 09 Aug 2026 20:49:33 +0800</lastBuildDate><atom:link href="https://rebel1725.codeberg.page/blog/zh/tags/qt/index.xml" rel="self" type="application/rss+xml" /><item>
            <title>使用 GammaRay 在 QtWidgets 应用程序中找到某个功能的实现</title>
            <link>https://rebel1725.codeberg.page/blog/zh/post/find-the-implementation-of-a-function-in-a-qtwidgets-application-using-gammaray/</link>
            <pubDate>Sun, 09 Aug 2026 20:49:33 +0800</pubDate><author>rebel1725@tilde.club (Rebel Zhang)</author>
            <guid>https://rebel1725.codeberg.page/blog/zh/post/find-the-implementation-of-a-function-in-a-qtwidgets-application-using-gammaray/</guid>
            <description>&lt;p&gt;为了实践自由软件的自由 1 和自由 3，和/或为自由软件社区做出贡献，我们需要修改与某个功能相关的源代码，让软件做出不同的事情。然而，由于我们对某个项目并不熟悉，我们常常不知道需要修改的源代码在哪里。你可以试着运行 &lt;code&gt;grep -R &amp;lt;some-user-facing-string&amp;gt; .&lt;/code&gt;，不过有时这并不会奏效（见&lt;a class=&#34;link&#34; href=&#34;../the-very-beginning-of-my-journey-contributing-to-the-free-software-community-existing-projects&#34; &gt;上一篇文章&lt;/a&gt;）。在那种情况下，我们就需要一些高级的软件内省工具。对于使用 Qt 开发的软件，一个强大的工具是 &lt;a class=&#34;link&#34; href=&#34;https://www.kdab.com/software-technologies/developer-tools/gammaray/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;GammaRay&lt;/a&gt;。&lt;/p&gt;&#xA;&lt;p&gt;要使用 GammaRay，你首先需要安装它。如果你想检查从发行版官方软件仓库安装的软件，那么也请从那里安装 GammaRay：&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# apt install gammaray&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;如果你使用 &lt;code&gt;kde-builder&lt;/code&gt; 开发 KDE 应用程序，请将以下几行添加到你的 &lt;code&gt;~/.config/kde-builder.yaml&lt;/code&gt;：&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;project gammaray:&#xA;  repository: https://github.com/KDAB/GammaRay.git&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;然后把它构建到你的工作目录中：&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;$ kde-builder gammaray&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;要使用 GammaRay，你需要先让你想检查的应用程序运行起来。然后启动 GammaRay，并在列表中选择你的应用程序。&lt;/p&gt;&#xA;&lt;p&gt;我们以在 Gwenview 中查找幻灯片逻辑为例。打开 Gwenview，然后打开一张图片，你会在菜单中看到 &lt;code&gt;Start Slideshow&lt;/code&gt; 选项：&lt;/p&gt;&#xA;&lt;p&gt;&lt;img alt=&#34;a screenshot of Gwenview&#34; class=&#34;gallery-image&#34; data-flex-basis=&#34;390px&#34; data-flex-grow=&#34;162&#34; height=&#34;952&#34; loading=&#34;lazy&#34; sizes=&#34;(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px&#34; src=&#34;https://rebel1725.codeberg.page/images/pic_20260809_001.png&#34; srcset=&#34;https://rebel1725.codeberg.page/blog/pic_20260809_001_9260183633641420788_hu_365916c355e33157.png 800w, https://rebel1725.codeberg.page/images/pic_20260809_001.png 1548w&#34; width=&#34;1548&#34;&gt;&lt;/p&gt;&#xA;&lt;p&gt;逐个浏览 Widgets 列表后，你会发现 &lt;code&gt;0x13bda470&lt;/code&gt; 就是我们想要检查的菜单，其中包含 &lt;code&gt;Start Slideshow&lt;/code&gt; 选项：&lt;/p&gt;&#xA;&lt;p&gt;&lt;img alt=&#34;GammaRay QtWidgets introspection&#34; class=&#34;gallery-image&#34; data-flex-basis=&#34;402px&#34; data-flex-grow=&#34;167&#34; height=&#34;1002&#34; loading=&#34;lazy&#34; sizes=&#34;(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px&#34; src=&#34;https://rebel1725.codeberg.page/images/pic_20260809_002.png&#34; srcset=&#34;https://rebel1725.codeberg.page/blog/pic_20260809_002_4293608996693979957_hu_43bd5ee0e43f111b.png 800w, https://rebel1725.codeberg.page/blog/pic_20260809_002_4293608996693979957_hu_c573a96130bd048e.png 1600w, https://rebel1725.codeberg.page/images/pic_20260809_002.png 1681w&#34; width=&#34;1681&#34;&gt;&lt;/p&gt;&#xA;&lt;p&gt;而且我们会在 Connections 标签页中看到一个 &lt;code&gt;toggle_slideshow&lt;/code&gt; QAction：&lt;/p&gt;&#xA;&lt;p&gt;&lt;img alt=&#34;Connections&#34; class=&#34;gallery-image&#34; data-flex-basis=&#34;304px&#34; data-flex-grow=&#34;126&#34; height=&#34;604&#34; loading=&#34;lazy&#34; sizes=&#34;(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px&#34; src=&#34;https://rebel1725.codeberg.page/images/pic_20260809_003.png&#34; width=&#34;767&#34;&gt;&lt;/p&gt;&#xA;&lt;p&gt;&lt;code&gt;grep&lt;/code&gt; 会告诉我们这样的 QAction 位于哪里：&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;~/kde/src/gwenview$ grep -R toggle_slideshow&#xA;app/fullscreencontent.cpp:    addAction(QStringLiteral(&amp;#34;toggle_slideshow&amp;#34;));&#xA;app/gwenviewui.rc:        &amp;lt;Action name=&amp;#34;toggle_slideshow&amp;#34; /&amp;gt;&#xA;app/mainwindow.cpp:        mToggleSlideShowAction = view-&amp;gt;addAction(QStringLiteral(&amp;#34;toggle_slideshow&amp;#34;), q, &amp;amp;MainWindow::toggleSlideShow);&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;在你常用的 IDE 中打开该项目，例如 Qt Creator，然后在 &lt;code&gt;app/mainwindow.cpp&lt;/code&gt; 中搜索这个字符串。我们会在这里找到 &lt;code&gt;toggle_slideshow&lt;/code&gt;：&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;        mToggleSlideShowAction = view-&amp;gt;addAction(QStringLiteral(&amp;#34;toggle_slideshow&amp;#34;), q, &amp;amp;MainWindow::toggleSlideShow);&#xA;        q-&amp;gt;updateSlideShowAction();&#xA;        connect(mSlideShow, &amp;amp;SlideShow::stateChanged, q, &amp;amp;MainWindow::updateSlideShowAction);&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;现在再搜索 &lt;code&gt;toggleSlideShow&lt;/code&gt;，它会带我们找到这个函数：&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;void MainWindow::toggleSlideShow()&#xA;{&#xA;    if (d-&amp;gt;mSlideShow-&amp;gt;isRunning()) {&#xA;        d-&amp;gt;mSlideShow-&amp;gt;pause();&#xA;    } else {&#xA;        if (!d-&amp;gt;mViewAction-&amp;gt;isChecked()) {&#xA;            d-&amp;gt;mViewAction-&amp;gt;trigger();&#xA;        }&#xA;        if (!d-&amp;gt;mFullScreenAction-&amp;gt;isChecked()) {&#xA;            d-&amp;gt;mFullScreenAction-&amp;gt;trigger();&#xA;        }&#xA;        QList&amp;lt;QUrl&amp;gt; list;&#xA;        for (int pos = 0; pos &amp;lt; d-&amp;gt;mDirModel-&amp;gt;rowCount(); ++pos) {&#xA;            QModelIndex index = d-&amp;gt;mDirModel-&amp;gt;index(pos, 0);&#xA;            KFileItem item = d-&amp;gt;mDirModel-&amp;gt;itemForIndex(index);&#xA;            MimeTypeUtils::Kind kind = MimeTypeUtils::fileItemKind(item);&#xA;            switch (kind) {&#xA;            case MimeTypeUtils::KIND_SVG_IMAGE:&#xA;            case MimeTypeUtils::KIND_RASTER_IMAGE:&#xA;            case MimeTypeUtils::KIND_VIDEO:&#xA;                list &amp;lt;&amp;lt; item.url();&#xA;                break;&#xA;            default:&#xA;                break;&#xA;            }&#xA;        }&#xA;        d-&amp;gt;mSlideShow-&amp;gt;start(list);&#xA;    }&#xA;    updateSlideShowAction();&#xA;}&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;继续搜索 &lt;code&gt;mSlideShow&lt;/code&gt;，你会找到这里：&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;struct MainWindow::Private {&#xA;    ...&#xA;    SlideShow *mSlideShow = nullptr;&#xA;    ...&#xA;}&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;现在我们知道 &lt;code&gt;d-&amp;gt;mSlideShow&lt;/code&gt; 的类型是 &lt;code&gt;SlideShow *&lt;/code&gt;。把鼠标悬停在 &lt;code&gt;SlideShow&lt;/code&gt; 这个字符串上，会告诉我们它的类型来自 &lt;code&gt;lib/slideshow.h&lt;/code&gt;。&lt;/p&gt;&#xA;&lt;p&gt;&lt;img alt=&#34;Qt Creator&#34; class=&#34;gallery-image&#34; data-flex-basis=&#34;271px&#34; data-flex-grow=&#34;112&#34; height=&#34;363&#34; loading=&#34;lazy&#34; sizes=&#34;(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px&#34; src=&#34;https://rebel1725.codeberg.page/images/pic_20260809_004.png&#34; width=&#34;410&#34;&gt;&lt;/p&gt;&#xA;&lt;p&gt;现在打开 &lt;code&gt;lib/slideshow.cpp&lt;/code&gt; 和 &lt;code&gt;lib/slideshow.h&lt;/code&gt;，你就可以继续往下找了。&lt;/p&gt;&#xA;</description>
        </item></channel>
</rss>
