EvilZone
Programming and Scripting => Scripting Languages => : Psycho_Coder 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 :
(http://i.imgur.com/H7uLJPu.png)
QSS File Code :-
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)
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
-
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.
-
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.
-
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 :)
-
This is cool 8) ..... which tutorial are you using?....if i may ask :)
-
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
-
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 :)
-
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! :)
-
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 :)
-
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.
(http://i62.tinypic.com/30lpizs.png)
the header file
#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
#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
#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
-
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.
-
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 :).