Author Topic: [Python] Simple PyQt5 GUI example with QSS Styling  (Read 4588 times)

0 Members and 1 Guest are viewing this topic.

Offline Psycho_Coder

  • Knight
  • **
  • Posts: 166
  • Cookies: 84
  • Programmer, Forensic Analyst
    • View Profile
    • Code Hackers Blog
[Python] Simple PyQt5 GUI example with QSS Styling
« on: August 20, 2014, 11:02:12 am »
Hello All,

I started reading about PyQt I decide to try the framework. Till now I had only worked with Java Swing. But after trying I seriously think that I might forget using Java Swing. I loved using PyQt5 since it is very easy and quite powerful, fast, and flexible. It does have more GUI features than Java (I don't know but with my experience in Java, I find Qt to be more mature.)

Since I have moved to Python 3.4 and hence decided to use the latest version and that is PyQt5 instead of PyQt4.

Today I will give you a little snippet that I wrote just as a part of learning the framework. I can't tell much about the efficiency of my code since I have very less experience with Python and Qt. So, if someone more experienced will comment or criticize my code then I am always open and would be very happy as well.

To develop this little GUI I used GridLayout and so the GUI and its widgets are adjustable with the base window. I used QSS to design the gui with colors.

QSS : Its a variant of CSS with most of the properties intersecting with CSS styles and specially designed to work and design the Qt guis and widgets. But instead of HTML tags we use the Widgets class name for styling them, like :- QWidget, QLineEdit, QLabel, QPushButton etc. etc.

QSS is a feature which I loved the most since everything else was pretty much the same with Java Swings.

ScreenShot :




QSS File Code :-


Code: (css) [Select]
QWidget {
    background-color: #222222;
}

QLineEdit {
    background-color: aliceblue;
    color: #618b38;
    font-style: italic;
    font-weight: bold;
}

QLabel {
    background-color: #222222;
    color: #618b38;
}

QPushButton {
    background-color: #8b0000;
    color: #ffffff;
    border-radius: 5px;
    border-style: none;
    height: 25px;
}




Code For GUI (Open the Spoiler)


Code: (python) [Select]
from PyQt5 import QtCore, QtWidgets

__author__ = "Psycho_Coder"


class MainUiWindow(object):

    def __init__(self):

        #Main Window
        self.centralwidget = QtWidgets.QWidget(MainWindow)

        """
        Using Grid Layouts for Widgets Alignment
        """
        #Grid Layout for Main Grid Layout
        self.maingrid_layout = QtWidgets.QGridLayout(self.centralwidget)

        #Grid Layout for Result Section Layout
        self.resultgird = QtWidgets.QGridLayout()

        #Grid Layout for Information section
        self.infogrid = QtWidgets.QGridLayout()

        #Grid Layout for holding all the widgets in place
        self.outergrid = QtWidgets.QGridLayout()

        #Button to clear all test input
        self.clearall = QtWidgets.QPushButton(self.centralwidget)

        #Button to show the final result by append
        self.showres = QtWidgets.QPushButton(self.centralwidget)

        #Horizontal layout to hold the result section horizontally
        self.horizontal_layout = QtWidgets.QHBoxLayout()

        """
        Show results widgets
        """
        self.fullname = QtWidgets.QLabel(self.centralwidget)
        self.result = QtWidgets.QLabel(self.centralwidget)

        """
        Get Names info section
        """
        self.firstname = QtWidgets.QLabel(self.centralwidget)
        self.lastname = QtWidgets.QLabel(self.centralwidget)

        #TextBox to get user input
        self.fname = QtWidgets.QLineEdit(self.centralwidget)
        self.lname = QtWidgets.QLineEdit(self.centralwidget)

    def init_gui(self, MainWindow):

        MainWindow.setObjectName("MainWindow")

        MainWindow.setStyleSheet(open("style.qss", "r").read())
        MainWindow.setAutoFillBackground(True)
        MainWindow.resize(328, 166)

        self.centralwidget.setObjectName("centralwidget")

        self.maingrid_layout.setObjectName("maingrid_layout")
        self.outergrid.setObjectName("outergrid")
        self.infogrid.setObjectName("infogrid")

        self.firstname.setObjectName("firstname")
        self.infogrid.addWidget(self.firstname, 0, 0, 1, 1)

        self.fname.setObjectName("fname")
        self.infogrid.addWidget(self.fname, 0, 1, 1, 1)

        self.lastname.setObjectName("lastname")
        self.infogrid.addWidget(self.lastname, 1, 0, 1, 1)

        self.lname.setObjectName("lname")
        self.infogrid.addWidget(self.lname, 1, 1, 1, 1)

        self.outergrid.addLayout(self.infogrid, 0, 0, 1, 1)

        self.fullname.setObjectName("fullname")

        self.result.setMaximumSize(QtCore.QSize(140, 16777215))
        self.result.setObjectName("result")

        self.resultgird.setObjectName("resultgird")
        self.resultgird.addWidget(self.fullname, 0, 0, 1, 1)
        self.resultgird.addWidget(self.result, 0, 1, 1, 1)

        self.outergrid.addLayout(self.resultgird, 1, 0, 1, 1)

        self.showres.setObjectName("showres")
        self.clearall.setObjectName("clearall")

        self.horizontal_layout.setObjectName("horizontal_layout")
        self.horizontal_layout.addWidget(self.showres)
        self.horizontal_layout.addWidget(self.clearall)

        self.outergrid.addLayout(self.horizontal_layout, 2, 0, 1, 1)
        self.maingrid_layout.addLayout(self.outergrid, 0, 0, 1, 1)

        MainWindow.setCentralWidget(self.centralwidget)

        self.retranslate_gui(MainWindow)

        #Add signals of clear to LineEdit widgets to clear the texts
        self.clearall.clicked.connect(self.result.clear)
        self.clearall.clicked.connect(self.lname.clear)
        self.clearall.clicked.connect(self.fname.clear)
        self.showres.clicked.connect(self.__name)

        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def __name(self):
        name = self.fname.text() + " " + self.lname.text()
        self.result.setText("<font color=\"#ffffff\"><b><u>" + name + "</u></b></font>")

    def retranslate_gui(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
       
        MainWindow.setWindowTitle(_translate("MainWindow", "Name Concatenation"))
        self.lastname.setText(_translate("MainWindow", "Last Name :"))
        self.firstname.setText(_translate("MainWindow", "First Name :"))
        self.fullname.setText(_translate("MainWindow", "Concatenated Name :-"))
        self.result.setText(_translate("MainWindow", "<Name>"))
        self.showres.setText(_translate("MainWindow", "Show Name!"))
        self.clearall.setText(_translate("MainWindow", "Clear All"))

if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)
    MainWindow = QtWidgets.QMainWindow()
    ui = MainUiWindow()
    ui.init_gui(MainWindow)

    MainWindow.show()
    sys.exit(app.exec_())



Since I am not a designer and so I can't design it more. There are many CSS experts so consult with them when making something by your own. I did as much as I could and to me it looked very pretty :epic:

I hope you like this short snippet (not short I guess :troll:) and probably you learnt a bit by observation how to design GUIs and use layouts properly and how the hierarchy should be followed.

Source

http://blog-psychocoder.blogspot.in/2014/08/pyqt5-simple-gui-example.html



Thank you,
Sincerely,
Psycho_Coder
« Last Edit: August 20, 2014, 11:38:53 am by Kulverstukas »
"Don't do anything by half. If you love someone, love them with all your soul. When you hate someone, hate them until it hurts."--- Henry Rollins

Offline Kulverstukas

  • Administrator
  • Zeus
  • *
  • Posts: 6627
  • Cookies: 542
  • Fascist dictator
    • View Profile
    • My blog
Re: [Python] Simple PyQt5 GUI example with QSS Styling
« Reply #1 on: August 20, 2014, 11:39:59 am »
Interesting. This is very much like android GUI development, but instead of XML you use CSS. +1
Also you cannot really compare Java Swing and PyQt, because they are made for very different languages.
« Last Edit: August 20, 2014, 11:40:51 am by Kulverstukas »

Offline Psycho_Coder

  • Knight
  • **
  • Posts: 166
  • Cookies: 84
  • Programmer, Forensic Analyst
    • View Profile
    • Code Hackers Blog
Re: [Python] Simple PyQt5 GUI example with QSS Styling
« Reply #2 on: August 20, 2014, 12:58:01 pm »
Interesting. This is very much like android GUI development, but instead of XML you use CSS. +1
Also you cannot really compare Java Swing and PyQt, because they are made for very different languages.

Yes I know. All I am saying that developing with PyQt is more fun and interesting than Java Swing. Also Java is my main programming language, the language I know best. I have worked a lot with swings but I found Qt to be better.

Thank you for your comments.
"Don't do anything by half. If you love someone, love them with all your soul. When you hate someone, hate them until it hurts."--- Henry Rollins

Offline RedBullAddicted

  • Moderator
  • Sir
  • *
  • Posts: 519
  • Cookies: 189
    • View Profile
Re: [Python] Simple PyQt5 GUI example with QSS Styling
« Reply #3 on: August 20, 2014, 04:57:15 pm »
Yes.. Qt is pretty awesome. I used it in some of my python thingies and lately decided to really learn Qt along with c++. Still working on my first application and I will post it as soon as the first basic functionality is done. Tbh I enjoy Qt a lot more since I use it with c++. Can't really describe why, guess its just because I learned so many new things since I started with it. I am pretty sure all of it can be done in pyQt too.. I just never read so much about it when I was using it with python :)
Deep into that darkness peering, long I stood there, wondering, fearing, doubting, dreaming dreams no mortal ever dared to dream before. - Edgar Allan Poe

Offline $Clone

  • Peasant
  • *
  • Posts: 86
  • Cookies: 5
  • $---Shadowalker---$
    • View Profile
Re: [Python] Simple PyQt5 GUI example with QSS Styling
« Reply #4 on: August 20, 2014, 10:19:21 pm »
This is cool 8) ..... which tutorial are you using?....if i may ask  :)

Offline Psycho_Coder

  • Knight
  • **
  • Posts: 166
  • Cookies: 84
  • Programmer, Forensic Analyst
    • View Profile
    • Code Hackers Blog
Re: [Python] Simple PyQt5 GUI example with QSS Styling
« Reply #5 on: August 20, 2014, 11:06:57 pm »
This is cool 8) ..... which tutorial are you using?....if i may ask  :)

I am following the tutorials on zetcode http://zetcode.com/gui/pyqt4/ but that doesn't covers QSS, I actually didn't learn QSS but I did most of the work with my prior experience with Swing. Its pretty much the same, I mean to say the concept in both cases are same. You just need to know the syntax.

Thats all :)

EDIT: QSS is not a part of Swing. I saw that we can use stylesheets in Qt and then I did it just like that :P, its very easy
« Last Edit: August 20, 2014, 11:08:17 pm by Psycho_Coder »
"Don't do anything by half. If you love someone, love them with all your soul. When you hate someone, hate them until it hurts."--- Henry Rollins

Offline $Clone

  • Peasant
  • *
  • Posts: 86
  • Cookies: 5
  • $---Shadowalker---$
    • View Profile
Re: [Python] Simple PyQt5 GUI example with QSS Styling
« Reply #6 on: August 21, 2014, 01:01:14 am »
by tha way +1 ....i really wanted to start pyqt since i saw your gui.....but the qss stuff is new to me...i know css.... but i will head up zetcode and start there pyqt tut.if you can post more of you learning i will be sure to follow  :)

Offline Architect

  • Sir
  • ***
  • Posts: 428
  • Cookies: 56
  • STFU
    • View Profile
    • Rootd IRC
Re: [Python] Simple PyQt5 GUI example with QSS Styling
« Reply #7 on: August 21, 2014, 02:34:51 am »
This is quite possibly the most beautiful non-bloat GUI I have seen here, and for that, we thank you. PyQT is very nice for such things. Good work! :)

Offline Psycho_Coder

  • Knight
  • **
  • Posts: 166
  • Cookies: 84
  • Programmer, Forensic Analyst
    • View Profile
    • Code Hackers Blog
Re: [Python] Simple PyQt5 GUI example with QSS Styling
« Reply #8 on: August 21, 2014, 08:15:02 am »
by tha way +1 ....i really wanted to start pyqt since i saw your gui.....but the qss stuff is new to me...i know css.... but i will head up zetcode and start there pyqt tut.if you can post more of you learning i will be sure to follow  :)

Yeah sure I will post more :)
"Don't do anything by half. If you love someone, love them with all your soul. When you hate someone, hate them until it hurts."--- Henry Rollins

Offline RedBullAddicted

  • Moderator
  • Sir
  • *
  • Posts: 519
  • Cookies: 189
    • View Profile
Re: [Python] Simple PyQt5 GUI example with QSS Styling
« Reply #9 on: August 21, 2014, 02:19:02 pm »
Hi,

I had a couple of free minutes and decided to create your form in c++. Its made in Qt4.8 and it does not compile if you use Qt5.X. The used stylesheet is the same as above. The form looks a bit different cause I used QFormLayout instead of the grid layout.



the header file
Code: (cpp) [Select]
#ifndef NAMECONCAT_H
#define NAMECONCAT_H

#include <QDialog>

class QLabel;
class QLineEdit;
class QPushButton;
class QString;
class QFormLayout;
class QHBoxLayout;
class QVBoxLayout;

class NameConcat : public QDialog
{
Q_OBJECT

public:
    NameConcat(QWidget *parent = 0);


private slots:
void onShowNameButtonClicked();
void onClearAllButtonClicked();
void onLineEditTextChanged(const QString &);

private:
QLineEdit *firstNameLineEdit;
    QLineEdit *lastNameLineEdit;
    QLabel *concatedNameLabel;

    QPushButton *showNameButton;
    QPushButton *clearAllButton;
};

#endif

the cpp file
Code: (cpp) [Select]
#include <QtGui>
#include "nameconcat.h"

NameConcat::NameConcat(QWidget *parent) : QDialog(parent) {
    firstNameLineEdit = new QLineEdit;
    lastNameLineEdit = new QLineEdit;
    concatedNameLabel = new QLabel(tr(""));

    showNameButton = new QPushButton(tr("&Show Name!"));
    showNameButton->setDefault(true);
    showNameButton->setEnabled(false);

    clearAllButton = new QPushButton(tr("Clear All"));
    clearAllButton->setEnabled(true);

    connect(firstNameLineEdit, SIGNAL(textChanged(const QString &)), this, SLOT(onLineEditTextChanged(const QString &)));
    connect(lastNameLineEdit, SIGNAL(textChanged(const QString &)), this, SLOT(onLineEditTextChanged(const QString &)));
    connect(showNameButton, SIGNAL(clicked()), this, SLOT(onShowNameButtonClicked()));
    connect(clearAllButton, SIGNAL(clicked()), this, SLOT(onClearAllButtonClicked()));

    QFormLayout *formLayout = new QFormLayout;
    formLayout->addRow(tr("&First Name:"), firstNameLineEdit);
    formLayout->addRow(tr("&Last Name:"), lastNameLineEdit);
    formLayout->addRow(tr("Concatenated Name:"), concatedNameLabel);

    QHBoxLayout *buttonLayout = new QHBoxLayout;
    buttonLayout->addWidget(showNameButton);
    buttonLayout->addWidget(clearAllButton);

    QVBoxLayout *mainLayout = new QVBoxLayout;
    mainLayout->addLayout(formLayout);
    mainLayout->addLayout(buttonLayout);

    setLayout(mainLayout);
    setWindowTitle(tr("Name Concatenation"));
    setWindowIcon(QIcon(":/images/windowIcon.ico"));
}

void NameConcat::onLineEditTextChanged(const QString &) {
    if (!firstNameLineEdit->text().isEmpty() && !lastNameLineEdit->text().isEmpty()) {
        showNameButton->setEnabled(true);
    }
}

void NameConcat::onShowNameButtonClicked() {
    QString concatedName = QString("%1 %2").arg(firstNameLineEdit->text(), lastNameLineEdit->text());
    concatedNameLabel->setText(concatedName);
}

void NameConcat::onClearAllButtonClicked() {
    firstNameLineEdit->clear();
    lastNameLineEdit->clear();
    concatedNameLabel->clear();
}

main.cpp
Code: (cpp) [Select]
#include <QApplication>
#include <QFile>
#include "nameconcat.h"

int main(int argc, char *argv[]) {
    QApplication app(argc, argv);
    NameConcat *dialog = new NameConcat;

    QFile File("style.qss");
    File.open(QFile::ReadOnly);
    QString StyleSheet = QLatin1String(File.readAll());

    qApp->setStyleSheet(StyleSheet);


    dialog->show();
    return app.exec();
}

for the icon of the window I used a ressource file. Guess thats a bit overkill for just one icon but I like to do it this way.
Here you can download the complete archive with all files: upload.evilzone.org/download.php?id=4104021&type=rar
Deep into that darkness peering, long I stood there, wondering, fearing, doubting, dreaming dreams no mortal ever dared to dream before. - Edgar Allan Poe

Offline Psycho_Coder

  • Knight
  • **
  • Posts: 166
  • Cookies: 84
  • Programmer, Forensic Analyst
    • View Profile
    • Code Hackers Blog
Re: [Python] Simple PyQt5 GUI example with QSS Styling
« Reply #10 on: August 22, 2014, 11:13:35 am »
No its perfect. The only think that you might think its different because of your Linux Desktop Manager. Qt integrates with the native GUI support and the change is perhaps because of the Window Manage which in my opinion is Enlightenment 19, is it ?

Everything look fine to me.
"Don't do anything by half. If you love someone, love them with all your soul. When you hate someone, hate them until it hurts."--- Henry Rollins

Offline RedBullAddicted

  • Moderator
  • Sir
  • *
  • Posts: 519
  • Cookies: 189
    • View Profile
Re: [Python] Simple PyQt5 GUI example with QSS Styling
« Reply #11 on: August 22, 2014, 11:40:46 am »
its openbox :) The difference is that I added the Concatenated Name QLabel and the QLabel which displays it to the QFormLayout. That aligns everything and there is no QSpacer or something that moves it down a bit. Thats why I said it looks a bit different. I also made the "show Name" QPushButton only active if the first name and last name QLineEdit has text. With the qss file this is not visible and I guess there should be a QPushButton:!enabled { ... } definition in the file (don't know if that works), I need to try it :).
Deep into that darkness peering, long I stood there, wondering, fearing, doubting, dreaming dreams no mortal ever dared to dream before. - Edgar Allan Poe