An ‘unfinished’ transaction is when an order ‘has incomplete/delayed/invalid payment details’. For example a payment not completed after being flagged (correctly or incorrectly) as fradulent will be marked ‘unfinished’. Recently I have been getting a lot more ‘unfinished’ transactions than usual through my main payment processor, Verifone. This seemed to be particularly for people ordering from the UK.
The brown bars show the ‘unfinished’ transaction rate for all countries. The blue bars show the ‘unfinished’ transaction rate for the UK. So my suspicions were correct – there has been a huge jump in ‘unfinished’ UK transactions. In March and April the number of unfinished transaction is about 10x what I would expect historically.
Some of these lost sales I am able to recover by emailing them and sending a Stripe payment link. But it isn’t ideal, as it is a hassle for me, and the customer and Stripe doesn’t handle the tax. But many of these sales are just lost for good.
I emailed some of the prospective customers with unfinished transactions. Here are a couple of responses I got:
“Hi my bank tell me that you are not set up with the new security banking system. That is why my payment is not going through.”
“I was told to ring my bank to ask why the payment was denied. I spent ages waiting for [my bank] to answer the phone and had to answer goodness knows how many security questions before they were able to tell me that the payment company had not updated their software to be on Visa’s list of acceptable people to pay. Something to do with preventing fraud.”
What is going on Verifone? Why has my ‘unfinished’ rate for UK customers sky rocketed? Is it going to be fixed soon? This is costing me time and money. Quite a lot of money. Is anyone else seeing the same thing?
I emailed Verifone on the 11th of March to ask what is going on. I am still awaiting a substantive reponse from Verifone, over a month later. It isn’t the first time I’ve had to send several follow-up emails and wait weeks for a response. Verifone support response times are glacial. Unfortunately great little payment processing companies frequently get bought and become not-so great large payment processing companies. Back when they were Avangate, you would often get a reponse on the same day. I miss those days.
** Update 10-Jun-2022 **
Things got even worse in May, with some 30% of UK customer transactions failings. I kept on at Verifone and I finally got an email on 23-May-2022:
“Thank you for the patience you have shown us during the investigation. Our development team has resolved the described issue and released the fix into the production environment. We have tested it and confirm that the fix is working as intended.”
The rejection rate then went very quickly back to normal. When I asked what the problem had been I was told:
“There was a setup issue with the GBP payment terminal. Our engineers identified and fixed it.”
So I am glad it is fixed. But it took from 11-Mar, when I first reported it, to 23-May, when it was reported fixed. It cost me a lot of time and and money. It must have cost Verifone a *lot* more, Possibly millions in commission for an operation of their scale. You would think they would have spotted and fixed something like this very quickly. But apparently not.
 I was originally with Avangate, who merged with 2Checkout and then were bought by Verifone.
This is a guest post from serial software entrepreneur Dennis Gurock.
Thinking about product positioning (and matching branding) is especially important if you build a product for a crowded market with many established competitors (and there are many reasons why this can be a good idea). We were in exactly this situation when we initially thought about building and marketing our new test management tool.
Positioning will allow you to better focus on a specific market segment to target, it makes it easier to build a clearer and stronger message to reach customers, and it helps develop the initial product vision and feature set.
What does successful positioning mean for software products? It can mean identifying a unique angle to focus on so you can stand out with your product among other products and competitors. Especially if you are entering a crowded market, this allows you to better communicate the key benefits and features you have to offer. It will help you reach the right customers and ensures that customers remember you when they look for a new product to try.
To come up with positioning for your new product, you can focus on a specific customer segment or niche that you think will be easier to market to or that you think is underserved by existing offerings. It can also help you limit the initial product scope, so you can go to market faster. Then rigorously optimizing for this initial customer segment allows you to establish a market presence and expand to other segments more easily later.
Why is positioning useful?
There are many benefits of coming up with and deciding on positioning for your new software product early on. Once you decide on the positioning, many marketing, product management and sales decisions become more straightforward.
Clear message & benefits: it is not easy to stand out in a crowded market. Positioning allows you to come up with clear messaging so you can explain and highlight unique selling points in few words.
Target and identify niche/marketing opportunities: it can be difficult to decide which marketing options to try, which campaigns to book and which niches to target. Focusing on a specific market segment based on the product positioning can be a great way to identify matching niches and opportunities.
Identify customer fit during sales: one of the most important aspects of the sales process is identifying and ensuring prospects are actually a great fit for your product. It’s wasted time for both you and for your prospects to invest a lot of effort evaluating and piloting a product if they will not benefit from it. Positioning can help you quickly filter and identify which customers to focus on.
Better focus on initial product vision: there are a lot of directions to choose when building a new product. If you don’t have a clear vision to guide you, it is easy to be distracted by different directions and work on too many things at the same time. Clear positioning makes it easy to focus product management on specific goals and use cases.
Easier to choose features: when you start working with customers, you will (hopefully) receive a lot of feedback on features you should add. Positioning helps you decide which of these features you should actually implement. Often times the most successful products are developed by following strong opinions and saying ‘No’ to many requests.
Examples of software product positioning
Let’s look at a few examples of companies that use positioning to market and build their products. All these examples are from industries and product categories with many existing competitors and products.
Testmo: we entered a crowded market with many established testing tools when we developed our new product. Most existing offerings either focus on manual testing, or they offer a complete ALM toolset to handle the entire development lifecycle. With Testmo we had other ideas and wanted to position it differently, focusing on unified testing. This means we combine test cases, automation and exploratory testing in a single platform. At the same time it allows us to limit the scope of the product. We won’t add our own issue tracking, or CI pipelines, or existing DevOps features. Instead of we focus on integrating with other tools customers already use.
Another example is the documentation and wiki product GitBook. They heavily focus on software developers and position themselves as the primary tool for developers to publish user docs and to document internal knowledge. With this positioning in mind, they can focus on features that primarily make sense for developers, such as Git synchronization, Markdown support and code snippets. It also allows them to more easily market directly to software developers with a clear message.
Then there’s the application monitoring service Checkly. There are many services and products that enable you to monitor apps and sites for downtime and notify you about issues. Checkly positions itself as a tool that enables end-to-end monitoring with flexible scripting. So it doesn’t just make simple web requests to see if a site is still live. It allows customers to write custom scripts to implement complex user flows and thereby not just check if a site is reachable, but also test the entire stack with the front-end, database, authentication and much more. This focus allows them to build more targeted features for advanced use cases and thereby provides more value to customers compared to simpler competitors.
The popular email marketing service Campaign Monitor also started with very focused positioning. In the first few years they concentrated on providing the best possible campaign tool for web designers and design agencies. This focus allowed them to invest more in features designers needed, such as white labeling, reusable themes and live email previews. Once they established their market presence, they started to expand their customer base to capture a larger part of the overall market for newsletter tools.
These are just some examples of companies and products that have benefited from clear positioning. Of course there are also countless of examples of companies choosing not to have such clear positioning. There is nothing wrong with this and you can certainly be very successful even if you ignore these points. But more often than not positioning is a useful tool to improve focus on specific goals and customer needs, which increases your chance to build a successful software business.
Dennis Gurock is one of the founders of Testmo, a QA testing tool that unifies test case management with exploratory testing and test automation in one platform. He has been working on products that help teams improve software quality for more than 15 years.
If you want to find out how to do something, such as do a mail merge in Word or fix a leaky valve on a radiator, where do you look first? Probably Youtube. Videos are an excellent way to explain something. More bandwidth than text and more scaleable than a 1-to-1 demo.
I’ve done explainer videos for all 3 of my products. But I found it a real struggle. I would write a script and then try to read the script and do the screencast at the same time and do it all in one take. I would stutter and stumble and it would take multiple attempts. It took ages and results were passable at best. I got some better software to edit the stumbles out, so I didn’t have to do it in one go. But it still took me a fair few attempts and quite a bit of editing. It became one of my least favourite things to do and so I did less and less of it.
Recently, I came across these slides on video by Christian Genco. These and subsequent Twitter exchanges with Christian convinced me that I should stop being a perfectionist about video and just start cranking them out on the grounds that a ‘good enough’ video is better than no video at all (‘the perfect is the enemy of the good’) and I would get better at it over time. As Stalin supposedly said “Quantity has a quality all of it’s own”.
So I have ditched the scripts and the perfectionism and I’ve managed to create 13 short Easy Data Transform explainer videos in the last week or so. And I am getting faster at it and (hopefully) a bit more polished. I’m definitely not an expert on this (and probably never will be) but here are some tips I have picked up along the way:
Get some decent software. I use Camtasia on Windows and it seems pretty good.
Try to talk slower.
Try to sound upbeat (not easy if you are British and could voice double for Eeyore).
Try not to move the mouse and talk at the same time. This makes editing a lot easier. Some people like to do the audio and the visual separately, but that seems like too much hassle.
If you stumble, just take a deep breath, say it again and then edit the stumble out later.
Get a reasonable mic. I have a snowball mic on a cantilevered stand. I covered it with a thin cloth to try to reduce pops.
The occasional ‘um’ is fine.
Have a checklist of things to do for each video, so you don’t forget anything (such as disabling your phrase expander software or muting the phone).
I’m lucky to have a very quiet office, so I don’t have much background noise to contend with.
Using Camtasia I can easily add intos and outros, edit out stumbles and add various effects, such a mouse position highlighting and movement smoothing. I just File>Save as the previous project so that I don’t have to re-add the intro and outro. Unsurprisingly, Camtasia have lots of explainer videos. I wish there was a way to automatically ‘ripple delete’ any sections where there is no audio and no mouse movement (if there is, I haven’t found it). Some people recommend descript.com. It looks interesting, but I haven’t tried it.
I did an A/B test of recordings with my Senheiser headset mic against my Snowball mic and the consensus was that the headset was ok but the the Snowball mic sound quality was better.
Some people prefer to use synthetic voices, instead of their own voice. While these synthetic voices have improved a lot, they never sound quite right to me. Also it must be time consuming to type out all the text. Or you can pay to have a professional voiceover done, but this is surprisingly expensive (around $100 per minute, last time I checked) and almost certainly more time consuming than doing it yourself.
Some people aren’t confident about speaking on videos because they are not native speakers of that language and have an accent. Personally accents don’t bother me at all. In fact I like hearing English spoken with a foreign accent, as long as I can understand it. Also I think there is an authenticity to hearing a creator talk about their product in their own voice.
I’m not a big fan of music on explainer videos, so I don’t add any.
I let Youtube generate automatic captions for people that want them (which could be people in busy offices and on trains and planes, as well as the hearing impaired). They aren’t perfect, but they are good enough.
My videos are aimed at least as much at finding new users as helping existing users. So I make sure I research keyword terms (mostly in Google Adwords) before I decide which videos to make and what to title them. Currently I am targetting very specific keyword searches, such as How to convert CSV to Markdown. Easy Data Transform can do a lot more than just format conversion, but from an SEO point of view it is better to target the phrases that people are actually searching for.
I upload the videos as 1080P (1920 x 1080 pixels) on to the Easy Data Transform Youtube channel and onto my screencast.com account (which I pay a yearly fee for). I then embed the screencast.com videos on relevant easydatatransform.com pages using IFRAME embed codes created by screencast.com. I don’t use the Youtube videos on my website, because I don’t want people to be distracted by Youtube ads and ‘you may also like’ recommendations. They might be showing a competitor! I don’t host the videos on the website itsself as I worry that might slow down the website. I also link to the videos in screencast.com from my help documentation, as appropriate.
Some people like to embed video of themselves in screencasts, in the hope of making it more engaging. But personally I want people to concentrate on my software, rather than being distracted by the horror of my face. And not having to comb my hair or look smart was part of what got me into running my own software business.
In the next few months I will be checking my analytics to see how many views these videos get and whether they increase the time on page and reduce the bounce rate.
If you can spare a few seconds to go to my Youtube page and ‘like’ a video ot two or subscribe, that would be a big help!
Note that some of the above doesn’t apply when you are creating a demo video for your home page, rather than an explainer video. Your main demo video should be slick and polished.
Easy Data Transform and Hyper Plan Professional edition are both on sale for 25% off at Winterfest 2021. There is also some other great products from other small vendors on sale, including Tinderbox, Scrivener and Devonthink. Some of the software is Mac only, but Easy Data Transform and Hyper Plan are available for both Mac and Windows (one license covers both). Sale ends 11th January.
This is a guest post from fellow software developer, Simon Kravis.
Few developers would choose their development platform on the merits of their respective Integrated Development Environments (IDEs) but it happens that applications developed in Windows need to be made available on the Mac platform.
There are many environments offering cross-platform (Mac, Windows and sometimes Android) functionality, but close inspection shows that they all have limitations. Visual Studio (the native Windows IDE) can produce apps which will run on a Mac using .Net Core – but only if they are command line apps on Windows. Other environments (like Xamarin) do support interfaces, but only involving simple controls like text boxes or drop-downs. There are other cross-platform IDEs (such as Qt) which offer better graphics support, but they are not cheap and the extent of their support is not evident. If you need functionality such as computer vision, there seems to be no alternative to creating a separate code base for the Mac. Once you start on this path it becomes obvious that Macs handle graphics (and interfaces) very differently from Windows.
Macs have evolved rather more than PCs over the decades: they abandoned their proprietary Mac operating system in favour of UNIX in 1999, adopting the NeXTSTEP platform created by NeXT. Apple originally used PowerPC chips, replacing them with Intel Core processors in 2006, and they are currently transitioning to RISC chips. The Mac NeXTSTEP programming language was Objective C, developed in the 1980s and this is still supported, although the modern Swift language was introduced in 2014, and the Xcode IDE appeared in 2003. Xcode is free, even for teams. It uses the Cocoa API, which is accessible from other environments. The current release (MacOS 13.0) supports both Objective-C and Swift and is also used for developing iPhone and iPad apps. Mac operating systems since Catalina (released in 2019) are 64-bit only. Xcode can only develop apps for Apple operating systems, notably iOS, which powers the iPhone. Most of the web questions and examples relate to iOS rather than MacOS. MacOS uses different frameworks from iOS, so some functions used in iOS are not available in MacOS, or have different parameters.
The Windows IDE (Visual Studio) dates from 1997, when it bundled together Visual Basic, Visual Fox Pro and Visual Source Safe and Visual C++. It has an open architecture based on plug-ins and supports 36 different programming languages, but the major ones are C#, VB.Net and C++. Visual Studio can develop apps for any platform via the .NetCore framework, but capability for non-Windows platforms is limited. The Community edition is free, and has almost all the functionality of paid versions.
Both Visual Studio and Xcode are highly complex applications. They both have graphical interface builders where controls are dragged from a library onto a form. Each application has a vocal supporters and detractors. My experience comes from about 5 years with Visual Studio developing C# applications. Before this I worked with Visual Basic for Applications in Microsoft Access, so I am well-versed in the Microsoft way of doing things.
Like most complex applications, Visual Studio and Xcode each have plenty of bugs, often producing completely unhelpful error messages. Reporting an Xcode bug through standard channels resulted in … nothing. Not even an automated message saying “Thank you for feedback. It will be used to improve future versions”. I haven’t even tried to report a Visual Studio bug, but I suspect that the much larger user base for Visual Studio will mean that workarounds are more readily available, even if the giant ship of Microsoft takes years to respond.
Moving to the Mac and Xcode for development was a shock as I found I didn’t know how to do the most basic things. String manipulation (used in most applications) in Objective C is highly verbose compared to C#. Google was invaluable for finding answers – mostly they were from Stack Overflow, but often from 10 or more years ago, sometimes from Apple Developer Forums. As Xcode has changed considerably since then, answers often had to be adjusted before they could be used. Another problem is that functionality once provided externally has since been incorporated into Cocoa, so attempts to find a current version of a component (or framework as they called in Cocoa) are often unsuccessful.
MacOS provides more native functionality than Windows. Features such as computer vision and PDF generation are included in MacOS, rather than requiring the use of 3rd party components, which may not as robust as desired, and may require a license for commercial use. However, documentation of MacOS functionality, if present at all, was rarely useful. A few times I asked questions on Stack Overflow which attracted the ire of the Mac gurus for either through having obvious (to them) answers or through not conforming to the forum guidelines (in their opinion). However, the integration of NuGet with Visual Studio provides easy access to the massive number of 3rd party libraries available for .Net on Windows.
The model-view-controller paradigm used on the Mac took some getting used to, as did the design of the main Xcode screen. Sometimes a useful display would disappear and I had difficulty in finding it how to bring it back. I often had to resort to retrieving earlier versions from the excellent Time Machine backup. Form design is similar on both platforms – dragging and dropping components from a library. Both Xcode and Visual Studio have bugs, as would be expected for such complex apps. Events from components are generated automatically in Windows, but have to be defined on the Mac (as Actions). References to the component you’ve added also need to be defined on the Mac (as Outlets) and are not a property of the component, whereas on Windows they are.
The Xcode environment provides only basic facilities from scratch: if you need to do something more sophisticated you’ll have to Google around to find out how. Once you know – it’s easy, but the learning curve for Xcode is much higher than for Visual Studio.
Rather than starting from scratch with the Mac version of my Caption Pro app, which uses local computer vision functionality to detect multiple photos, changes image dimensions and adds text to images, I found an existing open-source project on GitHub with similar basic functionality. This dated from 7 years ago and used Objective-C, so that was the language I opted for. An immediate handicap was that many of the answers I found to my questions used Swift in their example code, which is not interconvertible with Objective-C in the way that C# and VB.Net are. iOS applications for the iPhone (which are most common) use different frameworks from Mac apps, and routines in them sometimes have completely different syntax.
The user interfaces for the Mac and Windows versions look quite different, as shown below. There are some basic differences – menus appear separately to the application window on the Mac and are locked to the top of the screen, whereas Windows menus are part of the application screen. Toolbars offer access to common functionality on the Mac. Differences also arise from the fact the Mac application was adapted from existing code rather than created from scratch.
Open-source examples (often from GitHub) are useful, but rarely work out-of-the- box. Sometimes the modifications need are minor – like defining the development team- but sometimes it’s not possible to get them to build in a current version of Xcode.
Debugging on Xcode is frustrating – the call stack frequently contains assembler (which is perhaps why app performance tends to be better on Macs), and the debug variables window does not list all relevant variable values. Variable types may not be correct – Boolean values may appear as dates, and sometimes variables cannot even be evaluated by po (print out) statements. Printing out structure variables may show nothing. Despite the generally superior performance of Mac apps, building apps in Xcode appears to be much slower than in Visual Studio on similar vintage machines, and after code stops at a breakpoint, it may take a long time before the variables window is filled. Deployment of Mac apps can still be done on an ad-hoc basis, but you have to register as an Apple Developer to avoid blockages in installation arising from being an ‘untrusted source’. Bypassing these blockages is more than a matter of clicking “Install anyway” so it’s hard to avoid forking out US$100 per year for registration. Windows has similar blockages, which can be bypassed with a code-signing certificate. These certificates are available from many vendors, and are slightly cheaper than Apple developer registration, but the process of obtaining one may be very involved.
Ad-hoc deployment is somewhat easier on the Mac than on Windows, but the method of doing it via Archive generation is anything but obvious. Mac applications are actually disk images and applications keep all of relevant files in a folder. This makes uninstallation a matter of dragging the application icon into the recycle bin, a far simpler process than on Windows. dmg files are not recognized by IIS web servers (and may not be by Apache either), so unless the file type is registered, download from a web site will not be possible.
Apple pioneered the App Store for iPhones (it is the only way in which iPhone apps can be installed) and Mac apps can also be put there. Apple takes a commission of 30% (or 15% if you are a small company) and they review all apps before adding them. Passing the review process may be a lngthy process, as not all problems are detected in a review cycle. Fixing these issues and resubmitting may result in further problems coming to light. The review process may also be somewhat arbitrary. One App Store app presented an interface in German by default. English was available as Preferences option, but only after guessing where the Preferences option was located. App Store apps operate within a sandbox, which places restrictions on filesystem operations. Whether App Store deployment makes economic sense depends on the nature of the app, its market and price structure. Its advantages are that it targets the 16% of desktop users who use Macs, and streamlines installation (and payment, if applicable). The App Store supports ‘freemium’ pricing, where additional features are made available to paying users, but apps with free trial periods are shown as being free but with ‘in-app purchases’, which annoys some users.
Windows deployment can use .msi files, which have been around for decades, but are not easily installed by non-admin users. Self-extracting executables are more tractable, but 3rd party tools have to be used to create them. Windows 10 introduced Universal Windows Programs, which are easier to install and can be placed in the Microsoft Store, which operates in a similar way to the Apple App store, but for Windows desktops and tablets.
A key question which is very difficult to answer is “How long will it take me to convert my Windows app to run on a Mac?” Factors affecting this are app complexity, functionality and programmer skill. The time between starting work on the Mac app and first deploying it on the company web site was about 3 months, but the amount of time spent on the project each day varied between zero and 3 or 4 hours. If you are a paid resource, then the cost of a cross-platform IDE may be justified, but the requirement for local computer vision functionality added a great deal of complexity to my requirements, which is one reason why I opted for a separate code base. Substantial evaluation would be required before deciding if a cross-platform environment could support any required functionality.
Simon Kravis runs Aleka Consulting, a small software and consultancy company in Canberra, Australia specializing in information management and offering a number of software products. He has mainly developed scientific and engineering programs, starting in the era of paper tape.
I have been doing some recreational programming at play.battlesnake.com. It is a series of online leagues where you enter a program to play competitive ‘snake’.
The rules are pretty simple:
eat food to grow
die of starvation if you go too long without eating
die if you collide with a wall or the body of another snake
die if you collide head-on with another snake that if of equal size or bigger
last snake standing wins the match
There are also some variants, such as ‘royale’ where hazards move in from the walls.
You can program your snake in pretty much any language and host it where you like. When a match starts your program recieves JSON data with the board state and has 500 milliseconds to return either “left”, “right”, “up” or “down” for each move. You can write something super-simple (move to the nearest food, avoid other snakes) or you can get as complex as you like (machine learning or full game tree with alpha-pruning).
I have written my snake in Python (which seems appropriate) and host it on a free replit.com account. It uses a series of heuristics to decide it’s next action. It uses flood fill to assess how much space is available and A* for path finding.
You can see my snake (‘RhinoCrocoPede’) in action below, it is the purple one:
At the time of writing RhinoCrocoPede is 132nd in the global league (out of 450) and steadily rising.
The Battlesnake documentation is good and I was able to get the starter Python/Replit snake up and running in 15 minutes or so. I then just built on that. Replit is a nice online IDE. I did have issues with the free Replit account timing out. But I fixed this with a 90 day free upgrade code I found on the Battlesnake discord. This allowed me to set my REPL as ‘always’ on and ‘boosted’. I still have a fairly long ping time to the server (which is in California). This eats into my 500 milliseconds. But the time remaining is plenty for my current heuristic approach, even in Python.
If I wanted to get really serious I would rewrite my snake in C++, use a full game tree or Monte Carlo approach and host it on a fast server near the battlesnake server (to reduce ping time). But it is just a bit of fun and I don’t think I’ll get that serious.
My son has also written his own snake, which has been useful programming experience for him.
Battlesnake is really slick and well done. If you feel like doing some recreational programming, I recommend you give it a try.
Easy Data Transform and Hyper Plan Professional edition are both on sale for 25% off at Summer Festival 2021. There is also some other great products from other small vendors on sale, including Tinderbox, Scrivener and Devonthink. Most of the software is Mac only, but Easy Data Transform and Hyper Plan are also available for Mac and Windows (one license covers both). Sale ends tomorrow (13-Jul-2021)!
I’ve been an admirer of Garry Kasparov for a while. First for this chess, then for his insightful analysis of human and computer intelligence and more recently for his brave and principled stand against Putin. Turns out he is pretty good on Twitter as well!
I’m not too bothered about one ad being dissaproved. Especially during COVID, where almost no face-to-face events are happening anywhere in the world. But experience shows they will probably start disapproving many more over the next few weeks. I have clicked the link to appeal the disapproval. Hopefully, sometime in the next few weeks some under-paid, under-trained contractor, who might not speak great English, will re-approve the ad. But maybe not. Who can say in this opaque, Kafkaeaque, ‘computer says no’, outsourced world that we have collectively built for ourselves.
** Update 04-May-21 **
I appealed the dissaproval and the appeal failed. No reason given for why it is shocking. A second ad has been dissaproved for ‘shocking content’. I suspect many more will follow.
Dark themes are now available for Windows 10 and Mac and it is increasingly expected that desktop applications will offer a dark theme. Previously Qt support for dark themes was patchy. But I am happy to say that it now seems to work fine with Qt 5.12.2, and I have added dark themes to both Windows and Mac versions of my Easy Data Transform and Hyper Plan applications.
Easy Data Transform for Mac with a dark theme:
Easy Data Transform for Windows with a dark theme:
Hyper Plan for Mac with a dark theme:
Hyper Plan for Windows with a dark theme:
I haven’t decided yet whether to add a dark theme to PerfectTablePlan.
Adding dark themes was a fair amount of work. But a lot of that was scouring forums to work out how to integrate with macOS and Windows. Hopefully this article will mean you don’t have to duplicate that work.
Dark themes work a bit differently on Windows and Mac. On Windows changing the UI theme to dark won’t directly affect your Qt application. But you can use an application stylesheet to set the appearance. On Mac changing the UI theme to dark will automatically change your application palette, unless you explicitly block this in your Info.plist file (see below). On both platforms you will need to change any icons you have set to the appropriate light/dark version when the theme changes. Some of this may change in future as dark themes are more closely integrated into Qt on Windows and Mac.
You can add the following helper functions to a .mm (Objective-C) file:
Currently there seems to be no way to conect to a signal or event that shows the theme has changed in Windows. So I connected to a signal from a QTimer that fires every 5 seconds to check windowsIsInDarkTheme().
When the theme changes you potentially need to update any icons you have set, e.g. for the toolbar.
In a light theme you can usually set the active icons and let Qt calculate the corresponding disabled icons. This doesn’t work for a dark theme as you want the disabled icons to be darker than the enabled icons, rather than lighter. So you can either calculate the disabled icons programmatically or you can provide a set of disabled icons as well. I opted for the former.
Assuming your icons are set up as resources under :/icons/dark and :/icons/light you can do something like this:
QString getResourceName( const QString& iconName, bool dark )
return QString( ":/icons/%1/%2" ).arg( dark ? "dark" : "light" ).arg( iconName );
QPixmap getPixmapResource( const QString& iconName, bool dark )
QString resourceName = getResourceName( iconName, dark );
QPixmap pixmap = QPixmap( resourceName );
Q_ASSERT( !pixmap.isNull() );
QIcon getIconResource( const QString& iconName, bool dark )
QPixmap pixmap = getPixmapResource( iconName, dark );
icon.addPixmap( pixmap );
if ( dark )
// automatic disabled icon is no good for dark
// paint transparent black to get disabled look
QPainter p( &pixmap );
p.fillRect( pixmap.rect(), QColor( 48, 47, 47, 128 ) );
icon.addPixmap( pixmap, QIcon::Disabled );
Then you can reset the icon for the appropriate theme with: