<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: xiang,xin huang</title>
    <description>The latest articles on DEV Community by xiang,xin huang (@xiangxin_huang_82e9237e5).</description>
    <link>https://dev.to/xiangxin_huang_82e9237e5</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4102292%2F27f0ce0e-d691-490f-9416-cc52bc4b444b.png</url>
      <title>DEV Community: xiang,xin huang</title>
      <link>https://dev.to/xiangxin_huang_82e9237e5</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/xiangxin_huang_82e9237e5"/>
    <language>en</language>
    <item>
      <title>When should a QWidget animation stop its timer?</title>
      <dc:creator>xiang,xin huang</dc:creator>
      <pubDate>Mon, 14 Sep 2026 15:08:16 +0000</pubDate>
      <link>https://dev.to/xiangxin_huang_82e9237e5/when-should-a-qwidget-animation-stop-its-timer-17pk</link>
      <guid>https://dev.to/xiangxin_huang_82e9237e5/when-should-a-qwidget-animation-stop-its-timer-17pk</guid>
      <description>&lt;p&gt;A decorative animation can sit outside a scroll viewport while its widget still reports &lt;code&gt;isVisible() == true&lt;/code&gt;. A timer that only checks that property can keep advancing the animation even when the user cannot see it.&lt;/p&gt;

&lt;p&gt;Qt's &lt;a href="https://doc.qt.io/qt-6/qwidget.html#visible-prop" rel="noopener noreferrer"&gt;visibility documentation&lt;/a&gt; distinguishes a widget's visible state from whether it is actually exposed on screen. That distinction matters when deciding whether to run a repeating timer.&lt;/p&gt;

&lt;p&gt;This source walkthrough uses &lt;code&gt;ParticleBackdrop&lt;/code&gt; from Fluent-Qt 1.8.3, a Qt Widgets library maintained by this account. The component paints decorative particles with &lt;code&gt;QPainter&lt;/code&gt;. The useful part to examine here is how it decides to stop doing continuous work.&lt;/p&gt;

&lt;h2&gt;
  
  
  Compute the running state in one place
&lt;/h2&gt;

&lt;p&gt;The implementation combines three conditions:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="n"&gt;run&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;motionAllowed&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;inViewport&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;pauseWhenInactive&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt;
     &lt;span class="n"&gt;qApp&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;applicationState&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;Qt&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;ApplicationActive&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;motionAllowed()&lt;/code&gt; checks the local animation switch, positive speed, the widget's enabled state, the effective high-contrast theme, and the library's policy for continuous motion. &lt;code&gt;inViewport()&lt;/code&gt; checks visibility and rectangular clipping through the widget's ancestors. Application inactivity is a separate, configurable reason to pause.&lt;/p&gt;

&lt;p&gt;The timer only changes state when the result changes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;run&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;timer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;isActive&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;run&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;clock&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;start&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="n"&gt;timer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;start&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt;
    &lt;span class="n"&gt;timer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;stop&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="n"&gt;emit&lt;/span&gt; &lt;span class="n"&gt;q&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;animatingChanged&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;run&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This avoids restarting the timer whenever an unrelated event causes the conditions to be checked again. It also distinguishes the requested setting, &lt;code&gt;animationEnabled&lt;/code&gt;, from the effective state, &lt;code&gt;isAnimating()&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;See &lt;a href="https://github.com/calvinhxx/Fluent-Qt/blob/v1.8.3/src/components/layout/ParticleBackdrop.cpp#L128-L161" rel="noopener noreferrer"&gt;the running-state implementation&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Check clipping through the parent chain
&lt;/h2&gt;

&lt;p&gt;The visibility check begins with the component's local rectangle. For each parent, it translates the remaining rectangle into that parent's coordinates and intersects it with the parent's rectangle:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="n"&gt;QRect&lt;/span&gt; &lt;span class="n"&gt;clipped&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;q&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;rect&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;QWidget&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;child&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;q&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;QWidget&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;parent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;q&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;parentWidget&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
     &lt;span class="n"&gt;parent&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;parent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;parent&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;parentWidget&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;clipped&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;translate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;child&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;pos&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
    &lt;span class="n"&gt;clipped&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;=&lt;/span&gt; &lt;span class="n"&gt;parent&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;rect&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;clipped&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;isEmpty&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;child&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;parent&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When an ancestor moves its contents entirely outside a viewport, the intersection becomes empty. Checking only the component's own move events would miss changes caused by that ancestor.&lt;/p&gt;

&lt;p&gt;The component therefore installs event filters on its ancestors. Show, hide, move, resize, reparenting, and window-state events schedule another visibility check. A guarded &lt;code&gt;QTimer::singleShot(0, ...)&lt;/code&gt; combines pending checks and rebuilds the ancestor watch list after reparenting. The callback has the widget as its context.&lt;/p&gt;

&lt;p&gt;This is a rectangular clipping check. It does not detect every possible form of occlusion, such as another application covering the window or an overlapping sibling. Partially visible components still animate. That is the boundary of this implementation, and it should be kept explicit when adapting the approach.&lt;/p&gt;

&lt;h2&gt;
  
  
  Resume without advancing through the whole pause
&lt;/h2&gt;

&lt;p&gt;The elapsed-time clock restarts when animation resumes. Each timer callback then measures its actual elapsed interval and caps the step at 0.1 seconds before applying the speed multiplier:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;double&lt;/span&gt; &lt;span class="n"&gt;delta&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;min&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;clock&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;nsecsElapsed&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mf"&gt;1e9&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;.1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;clock&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;restart&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="n"&gt;elapsed&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="n"&gt;delta&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;speed&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;q&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;update&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The excerpt omits pointer and ripple bookkeeping. Resetting the clock excludes the paused interval; the cap limits the jump after a delayed callback. This choice fits a decorative effect, but a simulation that must track wall-clock time would need different behavior.&lt;/p&gt;

&lt;p&gt;The default timer interval is &lt;code&gt;qCeil(1000.0 / 30)&lt;/code&gt;, or 34 milliseconds. Treat this as an animation scheduling budget. &lt;a href="https://doc.qt.io/qt-6/qtimer.html#accuracy-and-timer-resolution" rel="noopener noreferrer"&gt;QTimer does not guarantee an exact frame rate&lt;/a&gt;, and window exposure can cause additional paints.&lt;/p&gt;

&lt;h2&gt;
  
  
  Test the transitions
&lt;/h2&gt;

&lt;p&gt;The &lt;a href="https://github.com/calvinhxx/Fluent-Qt/blob/v1.8.3/tests/components/layout/TestParticleBackdrop.cpp" rel="noopener noreferrer"&gt;component test source&lt;/a&gt; exercises these transitions for all three particle presets:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Move the component completely outside its parent, then move it back.&lt;/li&gt;
&lt;li&gt;Reparent it and move the new ancestor out of view.&lt;/li&gt;
&lt;li&gt;Hide the containing viewport.&lt;/li&gt;
&lt;li&gt;Disable local animation, enable reduced motion, or set speed to zero.&lt;/li&gt;
&lt;li&gt;Switch the effective theme to high contrast.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These checks inspect &lt;code&gt;isAnimating()&lt;/code&gt;, so a static image alone cannot make them pass. They describe timer behavior; they are not a battery-use benchmark. This walkthrough was checked against the tagged source and existing tests, without rerunning the test suite for the article.&lt;/p&gt;

&lt;p&gt;If you adapt this pattern, write down the exact conditions that stop your animation and the events that can change each condition. An otherwise correct predicate will still leave a timer running if nothing reevaluates it when an ancestor moves.&lt;/p&gt;




&lt;p&gt;AI disclosure: This article was prepared by an AI assistant at the project maintainer's request and checked against the linked source and Qt documentation. It does not present generated anecdotes or measurements as the maintainer's experience.&lt;/p&gt;

</description>
      <category>cpp</category>
      <category>qt</category>
      <category>performance</category>
    </item>
    <item>
      <title>Modernizing Qt Widgets without a QML rewrite</title>
      <dc:creator>xiang,xin huang</dc:creator>
      <pubDate>Mon, 31 Aug 2026 07:31:45 +0000</pubDate>
      <link>https://dev.to/xiangxin_huang_82e9237e5/modernizing-qt-widgets-without-a-qml-rewrite-9np</link>
      <guid>https://dev.to/xiangxin_huang_82e9237e5/modernizing-qt-widgets-without-a-qml-rewrite-9np</guid>
      <description>&lt;p&gt;I maintain &lt;a href="https://github.com/calvinhxx/Fluent-Qt" rel="noopener noreferrer"&gt;Fluent-Qt&lt;/a&gt;, an open-source C++ component library for Qt Widgets. The project started from a practical constraint: a mature desktop application may need a more modern interface, but rewriting the whole UI stack is often the least realistic way to get there.&lt;/p&gt;

&lt;p&gt;This is not an argument that Widgets are better than QML. QML is the right choice for many new applications. The narrower question is: &lt;strong&gt;how can an existing Widgets application modernize one screen at a time without replacing the parts that already work?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fnxufz18u8765ta2ridoy.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fnxufz18u8765ta2ridoy.jpg" alt="Fluent-Qt Gallery showing a Qt Widgets desktop interface" width="800" height="519"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  A UI rewrite changes more than pixels
&lt;/h2&gt;

&lt;p&gt;A production Qt Widgets application usually contains years of decisions around:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;QObject&lt;/code&gt; ownership and signal/slot wiring&lt;/li&gt;
&lt;li&gt;custom models, delegates, and validation&lt;/li&gt;
&lt;li&gt;native window behavior and platform workarounds&lt;/li&gt;
&lt;li&gt;CMake targets, packaging, and deployment&lt;/li&gt;
&lt;li&gt;accessibility, keyboard navigation, and input methods&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Moving all of that to another UI layer is not merely a visual refresh. It is a migration of behavior, test coverage, and operational knowledge.&lt;/p&gt;

&lt;p&gt;So I use a smaller migration boundary: preserve the application object model, event loop, and build workflow, then replace the visible layer only where the change is useful.&lt;/p&gt;

&lt;h2&gt;
  
  
  The incremental boundary
&lt;/h2&gt;

&lt;p&gt;For a one-screen modernization to be credible, I think it should satisfy four constraints:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Existing &lt;code&gt;QWidget&lt;/code&gt; layouts and application-owned models can remain in place.&lt;/li&gt;
&lt;li&gt;The application keeps its normal &lt;code&gt;QApplication&lt;/code&gt;, signals, slots, and events.&lt;/li&gt;
&lt;li&gt;The library links as an ordinary CMake target rather than introducing a parallel runtime.&lt;/li&gt;
&lt;li&gt;Old and new controls can coexist while a screen is migrated.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Fluent-Qt follows that boundary. Its reusable library depends on Qt Widgets and exposes C++ controls for input, navigation, collections, data grids, overlays, and windows. The current baseline is C++17 with Qt 5.15+ or Qt 6.2+.&lt;/p&gt;

&lt;h2&gt;
  
  
  The smallest useful integration
&lt;/h2&gt;

&lt;p&gt;For a new experiment, the library can be pulled in with &lt;code&gt;FetchContent&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cmake"&gt;&lt;code&gt;&lt;span class="nb"&gt;include&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;FetchContent&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nf"&gt;FetchContent_Declare&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    fluentqt
    GIT_REPOSITORY https://github.com/calvinhxx/Fluent-Qt.git
    GIT_TAG v1.7.5
    GIT_SHALLOW TRUE
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nf"&gt;FetchContent_MakeAvailable&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;fluentqt&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nb"&gt;target_link_libraries&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;my_app PRIVATE FluentQt::FluentQt&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The controls then participate in an ordinary Widgets layout:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;FluentQt/FluentQt.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;
&lt;span class="k"&gt;auto&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;button&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;fluent&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;basicinput&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Button&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;QStringLiteral&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Save changes"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;parent&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="n"&gt;button&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;setFluentStyle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;fluent&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;basicinput&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Button&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Accent&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="n"&gt;layout&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;addWidget&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;button&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The button itself is not the interesting part. The important point is what does &lt;strong&gt;not&lt;/strong&gt; change: the parent is still a &lt;code&gt;QWidget&lt;/code&gt;, the layout is still a Qt layout, and the control can connect to existing application slots.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;add_subdirectory()&lt;/code&gt; and installed-package &lt;code&gt;find_package(FluentQt CONFIG REQUIRED)&lt;/code&gt; integrations are also supported, so a team can choose the boundary that matches its dependency policy.&lt;/p&gt;

&lt;h2&gt;
  
  
  Evaluate the controls before installing anything
&lt;/h2&gt;

&lt;p&gt;I compiled the C++ Gallery to WebAssembly so the component set can be explored directly in a browser:&lt;/p&gt;

&lt;p&gt;👉 &lt;strong&gt;&lt;a href="https://calvinhxx.github.io/Fluent-Qt/gallery/" rel="noopener noreferrer"&gt;Open the live WebAssembly Gallery&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The Gallery is useful for checking component coverage, themes, states, and interaction ideas. It also makes the project's current surface visible instead of asking people to trust a feature list.&lt;/p&gt;

&lt;p&gt;There is an important limitation: a browser build is not proof of native desktop behavior. Window management, screen readers, IME input, drag-and-drop, packaging, and some platform-specific rendering still need verification on Windows, macOS, and Linux. I treat the WebAssembly build as an evaluation surface, not as a substitute for desktop acceptance testing.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I am trying to learn next
&lt;/h2&gt;

&lt;p&gt;Adding more controls is easy to measure. Proving that a library reduces the cost of modernizing a real application is harder—and more useful.&lt;/p&gt;

&lt;p&gt;The next step I want to document is one existing screen migrated in place, including the before/after diff, integration time, platform limitations, and the parts that should have remained plain Qt.&lt;/p&gt;

&lt;p&gt;If you maintain a Qt Widgets application, I would appreciate one concrete answer:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Which single screen or interaction is hardest to modernize in your codebase, and what makes it difficult?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;My current guesses are dense data views, navigation, overlays and dialogs, or custom window chrome. Real examples would help me choose a better case study than another isolated component demo.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/calvinhxx/Fluent-Qt" rel="noopener noreferrer"&gt;Source and installation guide&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://calvinhxx.github.io/Fluent-Qt/gallery/" rel="noopener noreferrer"&gt;Live C++ WebAssembly Gallery&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The project is MIT-licensed. Blunt feedback is welcome, especially from people maintaining long-lived desktop software.&lt;/p&gt;

</description>
      <category>qt</category>
      <category>cpp</category>
      <category>opensource</category>
      <category>showdev</category>
    </item>
  </channel>
</rss>
