A Basic Weakness, in my Polynomial Roots Finder (Resolved).

One of the subjects which I’ve written about often is that, in the past, I wrote a program which approximates the roots of polynomials, and more recently, that I wrote a version of the same program, that has a (Qt5-based) GUI – a Graphical User Interface. AFAICT, both versions of the program seem to work fine. The GUI version additionally displays a plot of the polynomial.

Note: Polynomials of a degree greater than 4 generally don’t have exact, algebraic solutions – with some exceptions – so that their roots are usually best found by numerical approximation.

Because I’ve published all the recent versions of this program on my blog, I also retest it thoroughly, with polynomials that I know will give it some difficulty each time. And what I have found was that presently, the simplified plotting window has a behaviour that is not false, but that may be difficult for the user to understand. This is less than ideal, because the purpose of that plotting window is, to make the polynomial which the user entered easier to understand, and not harder.

The problem manifests, if the user enters a polynomial that has exactly one root, or that has the same root with some multiplicity. In that situation, my plotting window will assume that the interval on the X-axis to be displayed, deviates from that root by ±0.25, which is also the smallest interval its internal logic allows it to display. While what it displays is not wrong, the very narrow range can make it hard to read:

 

Screenshot_20200904_062403

 

Here, I’ve used an established Computer Algebra System, to construct a polynomial that has a root of (0.5), with a multiplicity of 8. It’s a polynomial of the 8th degree. Its behaviour near (x=0.5) is the same as what the behaviour would be, of x8, near (x=0.0). In other words, the Y-values never get big, because, to raise some small fraction (x <= 0.25) to the power of 8, will always produce some even-smaller fraction.

But what the plot does non-ideally, is, to centre at (x=0.5) in this case, and only to cover the interval from (x=-0.25) to (x=0.75), as described above. The user must then read from the bottom of the plotting window, that the X-Tick-Interval is only (0.05), and must recognize that the plot is indeed centred at (x=0.5), 4 ticks after the labelled tick at (x=0.3). In this example, it’s easier to read the text-form of the solution.

The reason why my program does this, is the fact that its auto-determined interval spans the range of roots, adds some small fraction to that positively and negatively, but that in this case the spread between the roots is zero, because there is only one. And, I refuse to make the minimum span ±1.0, because some polynomials may in fact have roots closer together than that, which might also need to be plotted…

This program can be found at the following repository on my site:

https://dirkmittler.homeip.net/binaries/

The source code can be found in the files:

  • Dirk_Roots_GUI_1.tar.gz
  • Dirk_Roots_GUI_1.zip

And an AppImage can be found in the file:

  • Dirk_Roots_GUI_1-x86_64.AppImage

 

(Updated 9/04/2020, 15h40… )

Continue reading A Basic Weakness, in my Polynomial Roots Finder (Resolved).

Using QWidgetActions to place arbitrary widgets inside command-menus.

Again, on the subject of finding unusual ways to use the Qt GUI Library, to solve certain atypical problems that can exist in the design of applications. What a programmer might want to do, beyond giving his application command-menus, that fire Signals, which are received by Slots, which in turn evoke the capabilities of his or her program. The programmer may feel that he needs an entry in this command-menu to have an unusual appearance, such as, to consist of blue text, with a background that goes from being neutral to being yellow, when this entry is hovered over with the mouse…

Well, Qt has a special base-class for that sort of thing, which is called ‘QWidgetAction’. The idea behind it is, that it inherits the ‘QAction’ class, that would normally be added to the menus, but in such a way, that it additionally connects with a ‘QLabel’ object, which in turn can be given the most striking appearances, including rich text in the form of HTML.

This is what the result looks like:

Screenshot_20200821_021223_e

The ‘Reset Program’ command is different in appearance, from the other menu entries.

This is the code that was required, to make it happen:

The file ‘menubar.h‘ –

 


#ifndef MENUBAR_H
#define MENUBAR_H

#include "mainwindow.h"

class SimpleMenu : public QWidget
{

public:
    SimpleMenu(MainWindow *parent = 0);

};

class HoverWidget : public QLabel
{
public:
    HoverWidget(QWidget *parent);

    void enterEvent(QEvent * event);
    void leaveEvent(QEvent * event);
};

#endif // MENUBAR_H


 

The file ‘menubar.cpp‘ –

 


#include "menubar.h"
#include "mainwindow.h"
#include <QApplication>
#include <QMenu>
#include <QMenuBar>
#include <QWidgetAction>

SimpleMenu::SimpleMenu(MainWindow *parent)
    : QWidget(parent)
{

    QAction *quit = new QAction("&Quit", this);
    quit->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_Q));

//    QAction *reset_window = new QAction(this);
//    reset_window->setText("Re&set Program!");
//    reset_window->setShortcut(Qt::CTRL + Qt::Key_0);

    QAction *zoom_in = new QAction("Zoom I&n", this);
    QAction *zoom_out = new QAction("Zoom Ou&t", this);

    zoom_in->setShortcut(Qt::CTRL + Qt::Key_Plus);
    zoom_out->setShortcut(Qt::CTRL + Qt::Key_Minus);

    QMenuBar *toplev = new QMenuBar(parent);

    QMenu *file;
    file = toplev->addMenu("&File");
    file->addAction(zoom_in);
    file->addAction(zoom_out);
    file->addSeparator();
    file->addAction(quit);

    QMenu *help;
    help = toplev->addMenu("&Help");

    HoverWidget *reset_window_label = new HoverWidget(help);
    reset_window_label->setText("Reset Program            Ctrl+0");
    reset_window_label->setStyleSheet("QLabel {color: blue; margin: 4px}");
    QWidgetAction *reset_window = new QWidgetAction(this);
    reset_window->setDefaultWidget(reset_window_label);
    reset_window->setShortcut(Qt::CTRL + Qt::Key_0);

    help->addAction(reset_window);

    //  Qt5 Semantics for Signals sent to Slots...

    connect(quit, &QAction::triggered, qApp, &QApplication::quit);

    connect(reset_window, &QAction::triggered, parent, &MainWindow::resetQ);
    connect(zoom_in, &QAction::triggered, parent, &MainWindow::zoom_in_do);
    connect(zoom_out, &QAction::triggered, parent, &MainWindow::zoom_out_do);

}

HoverWidget::HoverWidget(QWidget *parent) :
    QLabel(parent)
{
    setAttribute(Qt::WA_Hover, true);
}

void HoverWidget::enterEvent(QEvent *event)
{
    setStyleSheet("QLabel {color: blue; background-color: yellow; margin: 4px}");
    QLabel::enterEvent(event);
}

void HoverWidget::leaveEvent(QEvent *event)
{
    setStyleSheet("QLabel {color: blue; margin: 4px}");
    QLabel::leaveEvent(event);
}

 

The exercise in which I tested this feature can be found at the following URL within my own site:

https://dirkmittler.homeip.net/binaries/

And, the relevant compressed archives are named ‘Creator_Test3.tar.gz‘ and ‘Creator_Test3.zip‘.

(This is a link to the previous exercise.)

 

(Update 8/22/2020, 17h40: )

Continue reading Using QWidgetActions to place arbitrary widgets inside command-menus.

This time, I used a QPainter object in a very ordinary way, as would be done in genuine GUI-building.

One project which I have been posting about has been, my ongoing effort to teach myself how to use the Qt5 GUI Library, which professional programmers do use in order to design Graphical User Interfaces – GUIs – for applications / programs. In fact, in a preceding posting, I wrote that I had discovered a deliberately unusual way to use one of the object classes in Qt 5.7.1, so that a ‘QImage’ object could be rendered to the screen of a computer, without first having to be transformed into a ‘QPixmap’ object. The ordinary thing to do would be, to transform it thus, first.

That trick can increase performance if two situations are met:

  • The graphical information could have started out as a bitmapped image, And
  • That image could have been unusually large, so that to have to buffer the entire image in its uncompressed form several times, could pose a considerable drain on the amount of memory that even modern computers should part with.

But, when designing GUIs, the starting point of the graphical information can be, simulated brush-strokes, with a simulated ‘QBrush’ and ‘QPen’, that are orchestrated by a programmer to give logical meaning to his GUI (beyond just adding the predefined widgets to it). In that case, the trick which I just wrote about will not gain anything over what I am about to describe.

When the ‘QPainter’ object and session are initialized, their target can be a ‘QPixmap’ object, and, after a sequence of painting instructions has finished, it can be assigned to a ‘QLabel’ widget once, by way of the ‘.setPixmap()’ function, thus resulting in a custom widget. Much buffering takes place, and, if the code has been written correctly, the graphic appears on the screen. The following is the graphic which my latest exercise generated:

Saved_Pattern

Admittedly, this does not correspond to the GUI of any real software. But hypothetically, it just as well might. In fact, ‘A Chess-Board’ is just as easy to construct, using the same methodology. Only, actually programming the computer to play Chess is a little harder. ;-)

The fact that I was able to post this graphic was partially due, to the added ability the Qt5 Libraries have, to Save a ‘QPixmap’ object, or a ‘QImage’ object, directly to the hard drive, using a simple, straightforward API, and to the format of a PNG File. That task is also achieved in the code sample I am about to link to.

The real caveat here is, Not to try doing funny stuff with the internal ‘.pixmap()’ pointer that belongs to the ‘QLabel’ object, because even though it can be done, writing to that internal property does not offer much in the way of performance improvements, when the goal is to design most GUIs.

(This is a link to the previous exercise.)

(Updated 8/21/2020, 21h25… )

Continue reading This time, I used a QPainter object in a very ordinary way, as would be done in genuine GUI-building.

How to make a QLabel widget display a QImage object, without first converting it to a QPixmap.

I have been studying the Qt v5.7.1 GUI Library on a private, informal basis, and making progress. As I was doing this, I observed a fact which is generally thought to be true, but which may not always be so.

GUI Libraries such as Qt have a set of object classes defined, which allow geometries to be drawn onto an abstract surface that exists in software, such geometries being Ellipses, Arcs, Rectangles, Polygons, Polylines, Chords etc.. Under Qt5, this is performed by way of the ‘QPainter’ class, together with a ‘QBrush’ and a ‘QPen’ class, and one out of several subclasses of the ‘QPaintDevice’ class. The crux of the operation is, that the ‘QPaintDevice’ class’s subclass needs to specify some sort of pixel buffer, so that the classes ‘QPixmap’ and ‘QImage’ certainly qualify. Multiple other classes also work. These pixel buffers are necessary physically, for the abstract drawing surface to ‘remember’ what the painting operations left behind, in the form of an image.

But what anybody who incorporates this into their Apps’ GUI will want to solve next is, to display the resulting pixel buffer. And an ugly way to do that, which is often used, is to select the ‘QPixmap’ class as the target, and then to do something like this:

 


void MainWindow::resetQ()
{
    delete sw_pixmap;
    sw_pixmap = NULL;
    sw_pixmap = new QPixmap(":/res/images/Unknown.jpg");
    int width = size().width();
    int height = size().height();
    i_label.setPixmap(sw_pixmap->scaled(width - 20, height - 50, Qt::KeepAspectRatio, Qt::SmoothTransformation));
}

 

The main problem with this is, that temporary pixmaps are being generated as arguments to function calls, by what I call ‘Naked Constructor Calls’. The compiler will generate temporary objects, and pass them in to the functions being called. And, because those objects were allocated on the stack, as soon as the function returns, they are just popped off the stack, hopefully in a way that results in no memory leaks.

When such temporary objects are simply complex numbers, I can still live with that, But in this case, they are pixel buffers!

Actually, I bent the truth slightly here. The way the function ‘setPixmap()’ is really prototyped, it accepts its argument via a reference. If this were not the case, the code above would truly become ridiculous. However, because of the way arguments are nevertheless presented and then forgotten, the ‘QLabel’ object that called this function still needs to create an internal copy of the pixel map, and must also deallocate the memory once replaced. Further, the temporary object created by ‘sw_pixmap->scaled()‘ is in fact a modified copy of ‘sw_pixmap’, and the compiler sees to it, that it gets deallocated, after the containing function call has returned. Whenever (larger) objects are returned from function-calls by value, they are stored in a special region of memory, managed by the compiler. (:4)

There has got to be a better way, in certain situations, to display whatever pixel buffer was painted to, from a QLabel object. And there is.

(This is a link to the previous exercise.)

(Updated 8/20/2020, 17h10… )

Continue reading How to make a QLabel widget display a QImage object, without first converting it to a QPixmap.