[HN Gopher] Show HN: Procal: A simple Qt-based programming calcu...
       ___________________________________________________________________
        
       Show HN: Procal: A simple Qt-based programming calculator
        
       Author : fellerts
       Score  : 148 points
       Date   : 2023-03-04 13:55 UTC (9 hours ago)
        
 (HTM) web link (github.com)
 (TXT) w3m dump (github.com)
        
       | themadsens wrote:
       | Hmm doesn't seem to do 64bit very well: 0xdeadbeefcafebabe ->
       | 0xdeadbeefcafeb800
       | 
       | Is the result by any means passing through a double? like in
       | freakin' JS!
        
         | fellerts wrote:
         | Good catch, that appears to be a bug! I'll have a look
         | tomorrow.
        
       | schemescape wrote:
       | I didn't realize you can use Qt from Python!
       | 
       | How is the developer experience for that? Anyone able to contrast
       | with Tkinter?
        
         | JasonFruit wrote:
         | The developer experience is great, though its approach is much
         | different from TKinter. The documentation is excellent, there
         | aren't maddening incomplete corners like GTK, the results look
         | good (if you think Qt looks good), and it's simple and
         | straightforward. The main downside is that sometimes your code
         | looks more like Qt and less like Python.
        
           | e4m2 wrote:
           | > The main downside is that sometimes your code looks more
           | like Qt and less like Python.
           | 
           | This can be remedied to a degree:
           | https://doc.qt.io/qtforpython/considerations.html#features
        
       | gfodor wrote:
       | Wow I'm reading Hacker's Delight and was just wondering if
       | something like this existed.
        
       | Devil5757 wrote:
       | Hi
        
         | nazgulsenpai wrote:
         | This comment looks like it was written by ChatGPT!
        
       | smolsky wrote:
       | LOL, nice! I wrote something quite similar a few years ago:
       | https://github.com/os12/calc
        
       | manchmalscott wrote:
       | I find it...mildly disconcerting that a calculator app where one
       | of the key motivations is "it's a hassle to copy + paste things
       | in" just chucks whatever you enter into eval().
        
         | frutiger wrote:
         | An expression you author executes on your machine. It's not
         | wholly unreasonable to use eval().
         | 
         | If it were executing third party input on your machine, then
         | it's a completely different ball game.
        
       | VadimPR wrote:
       | Qalculate! is my favourite GTK and Qt-based calculator that's
       | great at accepting all sorts of inputs, even solving for X:
       | https://github.com/Qalculate/qalculate-qt
        
         | EntrePrescott wrote:
         | I second that. Great program. Not only does Qalculate! also
         | handle binary operations and numbers of any base of your choice
         | (including hex, octal, binary), both for output and input (even
         | when working in another base, e.g. when the output mode is set
         | to decimal, you can just input hexadecimal values such as 0x1AF
         | and Qalculate! will understand)...
         | 
         | ... but most importantly it can calculate with units and show
         | the result converted to your liking e.g. you can write
         | 
         | 10 Nmx2pix20/minute to W and Qalculate will show the result as
         | 209,4395102 W. When you get used to that, you don't want to use
         | any calculator that doesn't have that feature any more.
        
       | ryanianian wrote:
       | Neat little project. Easy to setup and use.
       | 
       | Unfortunately with macOS's "Dark Mode" enabled the colors have
       | little or no contrast. And the UI renders very small for my eyes
       | (and compared to the demo gif). This is a criticism of Qt (or
       | maybe its python bindings) rather than this project. (Screenshot:
       | https://imgur.com/a/G9eAPoO)
       | 
       | I wonder if there's a way to shimmy in a "modern macOS Qt
       | renderer" or something into an existing project like this without
       | a rewrite?
        
         | fellerts wrote:
         | > I wonder if there's a way to shimmy in a "modern macOS Qt
         | renderer" or something into an existing project like this
         | without a rewrite?
         | 
         | Apparently there is. I hacked something together in a new
         | branch: https://github.com/fellerts/procal/tree/fredrik/theme.
         | Feel free to check it out and let me know how it works for you.
        
           | eql5 wrote:
           | I tried on macOS, yes dark mode works great now, thanks. But
           | I needed to change all QFont('monospace', 10) occurrences to
           | QFont('Monaco', 12)
           | 
           | in order to make it look nice.
        
             | fellerts wrote:
             | Thanks for trying it out. If you wouldn't mind, I'd
             | appreciate it if you could open an issue with a screenshot
             | of how the default behavior looked.
             | 
             | Edit: merged a fix for this, thanks for reporting.
        
             | pxc wrote:
             | Shouldn't it be your operating system's job (or yours) to
             | make the monospace font alias on your system point to a
             | nice font?
        
               | eql5 wrote:
               | In a perfect world, yes!
               | 
               | But in my experience with Qt, you always have to adjust
               | font names separately for every OS. This is especially
               | true for nice coding fonts.
               | 
               | If I had written that program, I would have brought my
               | own font (like "Hack"), and simply set the pixel size of
               | the font, to ensure it's exactly the same size on any OS
               | (and I would have written it in QML, with heavy usage of
               | Repeater, which would simplify the UI code a lot, but I
               | digress...).
        
         | fellerts wrote:
         | Thanks for checking it out.
         | 
         | You could play with the QT_SCALE_FACTOR environment variable to
         | fix the scaling issue at least. Something like this could work:
         | $ QT_SCALE_FACTOR=2 python procal.py
         | 
         | As for the colors, that's probably something this tool should
         | handle. I'll take a look to see if this is an easy fix.
        
       | p4bl0 wrote:
       | Cool link for the PyQt project example!
       | 
       | My daily calculator is `jupyter qtconsole` (formerly `ipython
       | qtconsole`). I've had it binded to Meta+Q forever and it is very
       | handy to have a full Python REPL which can occasionally display
       | graphs and stuff that can pop up at hand.
        
       | madduci wrote:
       | Do you think to port the code to C++ or do you think to keep it
       | in Python?
        
         | smolsky wrote:
         | LOL, here is my C++ implementation of the same concept:
         | https://github.com/os12/calc
        
         | fellerts wrote:
         | I wasn't planning on that, no. Is there a good reason to do so?
        
         | yoavm wrote:
         | What's wrong with Python? Do you find the calculator too slow?
        
       | recklesstodd wrote:
       | Similar concept but more oriented for embedded development:
       | https://www.heise.de/download/product/bitfummler-70589?hg=1&...
       | 
       | It includes a C interpreter and is very handy when manipulating
       | registers.
       | 
       | Unfortunately not open-source.
        
       | stephendause wrote:
       | Cool! Do you have any Web programming experience? If so, how
       | would you compare/contrast the experience coding in Qt vs.
       | JavaScript? I have ~1-2 years of experience programming in each,
       | and I tend to prefer Qt because to me, it seems easier to make
       | components that are truly reusable. On the other hand, there are
       | numerous advantages to Web programming, such as the fact that
       | it's easier to deliver content and it's ubiquitous.
        
         | jakear wrote:
         | Could you give an example (source code link) of a "truly
         | reusable" component?
        
           | ranger_danger wrote:
           | It's old but I still use it just fine with modern Qt
           | versions:
           | 
           | https://docs.huihoo.com/qt/solutions/4/qtcopydialog/qtcopydi.
           | ..
           | 
           | https://github.com/sintegrial/qtsolutions
        
           | stephendause wrote:
           | One that I have been thinking about lately is the
           | `QEnumComboBox` [1]. It takes the concept of a combobox (i.e.
           | drop down list/`select`) and combines it with a python `Enum`
           | to produce a very commonly desired functionality: allowing
           | the user to select a value and then converting it to an
           | `Enum`. This to me seems easily reusable because it
           | encapsulates that functionality in a clean way. I can't think
           | of a corresponding example in a JavaScript framework, but I
           | would love to see one. I think this might be more difficult
           | because one can't really pass types at runtime.
           | 
           | I think instead of "truly reusable" I should have said
           | something like "requires minimal configuration." I think
           | Python's reflection capabilities allow one to supply less
           | boilerplate when writing PyQt apps. This is just a subjective
           | impression that I have, and unfortunately I am having trouble
           | elaborating on this in a way that I think would be effective.
           | That is why I asked the author what they thought, since I am
           | wondering if anyone else has had this impression. However, I
           | will think about this more, and I might provide more examples
           | if I can think of them.
           | 
           | [1] https://pyapp-
           | kit.github.io/superqt/widgets/qenumcombobox/
        
             | jakear wrote:
             | I'm sure there's a million things out in reactland for
             | this, but even in vanilla JS it's pretty simple. I'd write
             | it something like this: https://github.com/JacksonKearl/JSE
             | numComboBox/blob/main/ind..., demo at
             | https://jacksonkearl.github.io/JSEnumComboBox/
             | 
             | Neither JS nor Python really have types at runtime or any
             | other time, but you can approximate them with Objects
             | and/or Classes (of course, I repeat myself ;) ). With some
             | TS magic you can even get the `setEnumClass` call to be
             | well typed, though if I were building it from scratch I'd
             | make the EnumClass prop immutable, too many weird corner
             | cases otherwise.
             | 
             | I've never worked extensively with Qt myself, but when
             | helping out a friend making Maya plugins in Qt we'd
             | occasionally hit SEGFAULTS from writing seemingly mundane
             | Python that'd crash all of Maya. That was enough to turn me
             | off of it, but looking through the docs you linked there
             | are some compelling components. It's nice to have a
             | component library separated from a specific framework (in
             | the React/VUE/etc. sense)... I don't know of any in JS.
             | Every framework seems to think their (incompatibile with
             | everything else) approach to reactivity is the hold grail,
             | and being modular across it would be impossible.
             | 
             | Though reconsidering, I suppose Qt is sorta the same...
             | it's just another framework and their "signals" aren't
             | Python. Ah well.
             | 
             | Diving deeper, signals are _weird_... they aren 't even
             | really part of the underlying C++! Some sort of strange new
             | modifier Qt invented at the level of
             | `private`/`public`/`protected` and such.
             | https://doc.qt.io/qt-6/signalsandslots.html
        
               | xenonite wrote:
               | I am not aware of Qt being the problem here, having built
               | large Qt apps that run stable (coding in C++ only). I
               | guess it is rather an issue with the Python to Qt
               | interface.
        
         | fellerts wrote:
         | Thanks! I come from the embedded world and my preferred
         | language is C - hence the need for a calculator that can wield
         | bits like this. I wrote this tool around 4 years ago and it was
         | my first attempt at creating anything that wasn't a CLI tool or
         | bare-metal firmware. In other words, I can't really compare
         | this experience to anything!
         | 
         | I guess the reason I chose Qt over any web-based frameworks is
         | I wanted a standalone app that would launch in a fraction of a
         | second and just do its job. I don't think a webapp (if that's
         | what they're called) would give me that. At the time, it seemed
         | that Qt would work well and, as a bonus, be cross-platform. I
         | had some Python experience to boot which helped.
         | 
         | Edit: I do have a personal site at https://www.fellerts.no/ but
         | it's entirely static, no real js to speak of.
        
           | billfruit wrote:
           | But Qt is a quite huge dependency, and has sort of turned
           | into a commercial product. If you were starting to develop
           | something similar today would you still choose Qt for it..
        
             | fellerts wrote:
             | Good question. If I want fast and cross-platform, GTK might
             | be a more viable option today. What would you choose for a
             | project like this in 2023?
        
               | ranger_danger wrote:
               | Qt hands down. I don't consider GTK particularly usable
               | or friendly, especially outside of Linux.
        
               | oynqr wrote:
               | This is so bad, even on Linux, that the experience of
               | trying to package a GTK4 libhandy application to the
               | distro I use made me permanently switch from Gnome to
               | KDE.
        
               | criddell wrote:
               | I'd pick the native toolkit for wherever I want to use
               | it. If I want it on Windows, I'd use C++ & Win32 / WinRT.
               | On mac, Swift + AppKit. For iOS, Swift + UIKit. For
               | Linux, probably C and GTK (I mostly use Gnome-based
               | distros).
               | 
               | I'd go 100% native because that's how you make the best
               | app for that platform. I also enjoy working with
               | different toolkits and if I wanted this on more than one
               | platform, I think I would enjoy designing and building it
               | for different environments. For example the version I'd
               | make for my small screen touch-based phone would probably
               | be significantly different than what I'd want on my
               | keyboard and mouse equipped big screen desktop.
               | 
               | A multi-platform or web-based solution would have too
               | many compromises.
        
               | jenadine wrote:
               | Slint? https://slint-ui.com
        
             | ognarb wrote:
             | Qt is not turning into a commercial project. It has always
             | been a project which is dual licensed under GPL (and later
             | some of the modules were also licensed under LGPL) and a
             | commercial license.
             | 
             | It's just that the Qt company always tries to make it non-
             | clear that Qt is not open source to drive their sales.
             | 
             | Regarding bloat, Qt is quite modular and if you want just
             | the widgets you only need QtBase and none of the additional
             | modules.
        
               | ranger_danger wrote:
               | most components are LGPL not GPL. also after I think it
               | was Qt 5.6, they switched to LGPLv3 instead of v2, so the
               | anti-tivoization clause applies.
        
       | MatthiasPortzel wrote:
       | One feature that I'd love in a programming calculator is the
       | ability to set arbitrary bit widths. 32bit or 64 bit is okay, but
       | a lot of the time when I'm thinking about individual bits; it's
       | because I'm doing embedded programming for 8 or 16 bit devices.
       | Similarly, the ability to toggle signed and unsigned
       | representations.
        
         | recklesstodd wrote:
         | Have a look at this:
         | https://www.heise.de/download/product/bitfummler-70589?hg=1&...
        
         | fellerts wrote:
         | I totally agree, which is why I included that in procal! Just
         | right-click a cell to turn it into a sign bit.
        
           | SimDeBeau wrote:
           | Thats really convenient, but probably not the most
           | discoverable.
        
             | fellerts wrote:
             | Fair point. At least it's mentioned in the README. My goal
             | was a lean and efficient tool without any extra fluff, so
             | discoverability took a hit.
        
           | MatthiasPortzel wrote:
           | I did not notice that. I will have to download procal and
           | give it a try.
        
       | not_the_fda wrote:
       | I believe your license is incorrect. PyQt is licensed either
       | commercial or GPL, so you would have to either purchase a license
       | or license this under GPL verses the more permissive MIT license
       | you are using.
        
         | fellerts wrote:
         | Thanks! I changed the license to GPLv3.
        
           | sho_hn wrote:
           | Note your alternative would be to use the official "Qt for
           | Python" (aka PySide) bindings. Those are LGPL, which is one
           | of the main reasons they exist (PyQt was started earlier but
           | unlike much of Qt is not LGPL).
           | 
           | This is from when Qt still cared about LGPL, i.e. the Nokia
           | days when the aim was to be the commercial-friendly Nokia
           | SDK.
        
         | jenadine wrote:
         | I don't think that's right. The MIT license is compatible with
         | the GPL. One can license the code using a GPL library using
         | MIT. Only someone who wants to fork the code into a proprietary
         | program would needs to purchase a license of the dual-licensed
         | library.
        
           | fellerts wrote:
           | IANAL, but the top answer in this thread seems to suggest
           | otherwise:
           | https://opensource.stackexchange.com/questions/1640/if-im-
           | us...
           | 
           | > No; incorporating or linking against GPL requires that your
           | project-as-a-whole be distributed under GPL. But you can
           | include MIT licensed parts (or another GPL-compatible
           | license) in the project. Also, it depends.
        
             | jenadine wrote:
             | That answer is for a pure GPL library, not dual licensed.
             | 
             | As the quoted part says: the project as a whole (which
             | includes the library itself) need to be GPL, but part of it
             | can be MIT. So the code of the program on GitHub can be
             | MIT.
        
               | mtrower wrote:
               | The other half of the dual license is commercial. They
               | can purchase a license and use it under the commercial
               | terms, or use it for free under the GPL terms.
               | 
               | Under the GPL terms, the derived work becomes GPL (this
               | is why people call GPL infectious or viral). The project
               | may include unrelated MIT components alongside GPL
               | components, but the project itself becomes GPL, along
               | with any derived components (i.e. components making use
               | of the GPL components). It's kind of the entire point of
               | the GPL. It's also why we ended up with LGPL, which
               | offers a linking exception.
        
               | jenadine wrote:
               | I disagree. The GPL can't force a license on your code.
               | It just force a license on the whole program that all its
               | components must respect the freedom of the GPL. As long
               | as the code that use the GPL is under a GPL compatible
               | license (such as MIT), you're good. I.e: you're free to
               | give more freedom in your code than the ones required by
               | the GPL.
               | 
               | The virality is something else: It is that you must
               | disclose the source of the whole program that use a GPL
               | only library. And you're doing that with MIT
        
               | MatthiasPortzel wrote:
               | You do have to license the whole program as GPL, but as
               | you say, you are free to duel-license parts of the code
               | with a more-permissive license.
               | 
               | https://www.gnu.org/licenses/gpl-
               | faq.html#GPLModuleLicense
        
           | not_the_fda wrote:
           | You can use a library that has an MIT license with a library
           | that has a GPL license, that's what it means to be
           | compatible. But the end work would have to be under the GPL
           | license.
           | 
           | Its the whole reason PySide exists, to have a Qt Python
           | library hat is LGPL to allow works that use it not have to be
           | GPL like PyQt does.
        
             | jenadine wrote:
             | The reason PySide exist under LGPL is to allow proprietary
             | program using the library. Here we are talking about MIT
             | which is not proprietary.
        
               | not_the_fda wrote:
               | See https://en.wikipedia.org/wiki/License_compatibility
               | GPL Compatability
               | 
               | "That is, their code can be combined with a program under
               | the GPL without conflict, and the new combination would
               | have the GPL applied to the whole (but the other license
               | would not so apply)."
        
       | amelius wrote:
       | This would be even better if it integrated with every desktop
       | program out there.
       | 
       | E.g. if you want to compute the width of some object in Inkscape
       | or Freecad, using some formula not supported by those programs.
        
         | fellerts wrote:
         | I used to have xclip integration in procal that would copy any
         | selected text into the input field for just this purpose.
         | However I removed it because it wasn't particularly useful and
         | got in the way of "normal calculating" (apparently I select
         | text quite frequently). Let me know if you think of a usage
         | pattern that would make sense!
        
       | ThePhysicist wrote:
       | I love PyQt, I wrote lots of graphical user interfaces for my lab
       | equipment during my PhD, was super easy to wire stuff up and
       | replace Labview with Python. The design was similar to this app,
       | simple frontend that allowed you to e.g. set microwave
       | frequencies, toggle outputs or make measurements. My colleagues
       | were initially quite skeptical but 10 years later they're still
       | using the software and it spread to other labs, they even hired a
       | full-time developer to work on it.
        
         | dekhn wrote:
         | I use PyQt to write an entire interface to my self-built
         | microscope. It's awesome. Personally, i design the UI in Qt
         | Designer, then wire it up in code. The absolute gem of gems in
         | Qt is the Graphics View Framework, which is a retained scene
         | graph for 2D rendering with extraordinary power and
         | performance. I can do realtime work with the scope including
         | image processing all from python but at C++ speeds.
        
           | spacechild1 wrote:
           | QGraphicsView is indeed awesome. I have been using it in the
           | tile map editor of my hobby 2D game engine and it can easily
           | handle thousands of objects. IIRC, it uses spatial
           | partitioning to determine which objects need to be redrawn.
        
         | appveyor wrote:
         | Flet (https://flet.dev) is a new GUI library for Python to
         | write apps like that. It uses Flutter to render UI with a
         | modern-looking Material design. Your app can be run as a
         | desktop app and published as a web app (standalone with Pyodide
         | or server-driven with built-in web server).
        
           | [deleted]
        
         | fellerts wrote:
         | Indeed! And with PyQtGraph you can create live graphs and
         | visualizations that update at 100 Hz or more. It's really fun.
        
       ___________________________________________________________________
       (page generated 2023-03-04 23:00 UTC)