## Touching Up Some More Source Code

In This previous posting, I had already described a problem that can exist, with my amateur attempts to build “Graphical User Interfaces” – GUIs – where the application window could lack a basic feature, that being, when the user resizes it – or, when the O/S resizes it because the desktop is too small for the application window’s default size – certain behaviours in the window are supposed to update but did not.

Specifically, it is not automatic that the Layout Widget, that spaces out sub-widgets in the main application window, also resizes, when the application window does so.

And so, there was a second application which I wrote, where I thought it would be meaningful to update the source code, to the correct behaviour.

In this case, that very minor update to the source code brought on greater complexity, because I did, in fact, compile Windows 32-bit and Windows 64-bit binaries for it. And additionally, I provided the updated Linux, 64-bit AppImage. The affected files can be found here:

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

And the downloadable files are the ones with naming that begins with ‘Dirk_Roots_GUI_1...‘.

Enjoy,
Dirk

## Learning PyQt

One of my recent undertakings has been, to extend my knowledge of Python, which I was previously only capable of writing procedural code for, to include, how to write Object-Oriented Python.

In the process, I began to think of what advantages I might now have, with that ability. And one answer which presented itself was of the form, ‘I already know enough about the Qt Library, to use it for some C++ programs. It has a Python binding referred to sometimes as PyQt. With the ability to write Object-Oriented Python, I should also gain the ability to write GUI applications in Python – eventually.’

The result of my recent exercise can be found at this URL:

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

The compressed files which contain my first project using PyQt are named ‘PyQt_Test_1_s.gz‘ and ‘PyQt_Test_1_s.zip‘. Either of those compressed archives need to be unzipped to a folder, in which there should be a total of 4 Python scripts. Python 3 would need to be run on the script named ‘AppStart.py‘.

I’m sorry to start so small.

Oh, yes… In order for these scripts to run, the reader’s Python installation would need to include PyQt5. Not all do.

Dirk

## 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:

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‘ –



#include "mainwindow.h"

{

public:

};

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

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




The file ‘menubar.cpp‘ –


#include "mainwindow.h"
#include <QApplication>
#include <QWidgetAction>

: 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);

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);

//  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: )

## 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:

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… )