analitics

Pages

Wednesday, December 5, 2018

PySide2 and PyQt versions.

A short intro about this python module named PySide2 can be found on the Wikipedia webpage.
The purpose of this tutorial is to introduce concepts about licenses and develop python programs using ergonomic design interfaces with PySide2 and PyQt versions.

PySide2 is a Python binding of the cross-platform GUI toolkit Qt, currently developed by The Qt Company under the Qt for Python project. It is one of the alternatives to the standard library package Tkinter.
...
PySide was released under the LGPL in August 2009 by Nokia,[1] the former owners of the Qt toolkit, after Nokia failed to reach an agreement with PyQt developers Riverbank Computing[7] to change its licensing terms to include LGPL as an alternative license.
...


Now about the LGPL software license:

The GNU Lesser General Public License (LGPL) is a free software license published by the Free Software Foundation (FSF). The license allows developers and companies to use and integrate software released under the LGPL into their own (even proprietary) software without being required by the terms of a strong copyleft license to release the source code of their own components.

I wrote in the past about PySide and you can find on this blog or on my website.
Let's start installing Python using pip3.6.
C:\Python364>cd Scripts

C:\Python364\Scripts>pip3.6.exe install PySide2
Collecting PySide2
  Downloading https://files.pythonhosted.org/packages/10/ba/7448ec862655c356ade2
2351ed46c9260773186c37ba0d8ceea1ef8c7515/PySide2-5.11.2-5.11.2-cp35.cp36.cp37-no
ne-win_amd64.whl (128.7MB)
    100% |████████████████████████████████| 128.7MB 44kB/s
Installing collected packages: PySide2
Successfully installed PySide2-5.11.2
The PySide2 python module is another way to connect Qt with Python modules.
You can take a look at this python module at Qt website .
The source code is more simple but this can put the development in trouble if you try to follow the PyQt way.
Let's see a simple example. I create the main window for this example.

The layout of this window named main_layout is split into two: secondary_splitter_1 and secondary_splitter_2.
Into this, I add for each area the defined class named SecondaryWindow.
The four variables for this SecondaryWindow class are named like secondary_window_1, secondary_window_2, secondary_window_3 and secondary_window_4.
Interface programming with PySide2 and PyQt keeps a classic form of statements and then structured implementations. It seems simpler to create interfaces with PySide, but the development and community interest seems to be attracted to PyQt.
In both cases, the programming speed in the python programming language is required.
Error management is simpler and more limited in PySide2. I have noticed PyQt essential changes in developing even more advanced versions (see PyQt4 and PyQt5).
Let's see the source code:
import sys
from PySide2 import QtGui, QtCore, QtWidgets
from PySide2.QtGui import *
from PySide2.QtCore import *
from PySide2.QtWidgets import *

class SecondaryWindow(QtWidgets.QWidget):

    def __init__(self, label, parent=None):
        super(SecondaryWindow, self).__init__(parent)

        self.label = QtWidgets.QLabel(label, parent=self)
        self.label.setAlignment(QtCore.Qt.AlignCenter)
        self.label.setStyleSheet("QLabel {font-size:18px;color:blue}")

        self.main_layout = QtWidgets.QVBoxLayout()
        self.main_layout.addWidget(self.label)
        self.setLayout(self.main_layout)

class MainWindow(QtWidgets.QWidget):

    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)

        self.secondary_window_1 = SecondaryWindow("1", parent=self)
        self.secondary_window_2 = SecondaryWindow("2", parent=self)
        self.secondary_window_3 = SecondaryWindow("3", parent=self)
        self.secondary_window_4 = SecondaryWindow("4", parent=self)

        self.secondary_splitter_1 = QtWidgets.QSplitter(QtCore.Qt.Horizontal, parent=self)
        self.secondary_splitter_1.addWidget(self.secondary_window_1)
        self.secondary_splitter_1.addWidget(self.secondary_window_2)

        self.secondary_splitter_2 = QtWidgets.QSplitter(QtCore.Qt.Horizontal, parent=self)
        self.secondary_splitter_2.addWidget(self.secondary_window_3)
        self.secondary_splitter_2.addWidget(self.secondary_window_4)

        self.main_splitter = QtWidgets.QSplitter(QtCore.Qt.Vertical, parent=self)
        self.main_splitter.addWidget(self.secondary_splitter_1)
        self.main_splitter.addWidget(self.secondary_splitter_2)

        self.main_layout = QtWidgets.QVBoxLayout()
        self.main_layout.addWidget(self.main_splitter)
        self.setLayout(self.main_layout)

        self.setWindowTitle("PySide2 example")
        self.resize(220, 220)

if __name__ == "__main__":
    app = QApplication(sys.argv)
    main_window = MainWindow()
    main_window.show()
    sys.exit(app.exec_())

Thursday, November 29, 2018

Python Qt5 : submenu example.

Using my old example I will create a submenu with PyQt5.
First, you need to know the submenu works like the menu.
Let's see the result:

The source code is very simple:
# -*- coding: utf-8 -*-
"""
@author: catafest
"""
import sys
from PyQt5.QtWidgets import QMainWindow, QAction, qApp, QApplication, QDesktopWidget, QMenu
from PyQt5.QtGui import QIcon

class Example(QMainWindow):
    #init the example class to draw the window application    
    def __init__(self):
        super().__init__()    
        self.initUI()
    #create the def center to select the center of the screen         
    def center(self):
        # geometry of the main window
        qr = self.frameGeometry()
        # center point of screen
        cp = QDesktopWidget().availableGeometry().center()
        # move rectangle's center point to screen's center point
        qr.moveCenter(cp)
        # top left of rectangle becomes top left of window centering it
        self.move(qr.topLeft())
    #create the init UI to draw the application
    def initUI(self):               
        #create the action for the exit application with shortcut and icon
        #you can add new action for File menu and any actions you need
        exitAct = QAction(QIcon('exit.png'), '&Exit', self)        
        exitAct.setShortcut('Ctrl+Q')
        exitAct.setStatusTip('Exit application')
        exitAct.triggered.connect(qApp.quit)
        #create the status bar for menu 
        self.statusBar()
        #create the menu with the text File , add the exit action 
        #you can add many items on menu with actions for each item
        menubar = self.menuBar()
        fileMenu = menubar.addMenu('&File')
        fileMenu.addAction(exitAct)
        
        # add submenu to menu 
        submenu = QMenu('Submenu',self)

        # some dummy actions
        submenu.addAction('Submenu 1')
        submenu.addAction('Submenu 2')
           
        # add to the top menu
        menubar.addMenu(submenu)
        #resize the window application 
        self.resize(640, 480)
        #draw on center of the screen 
        self.center()
        #add title on windows application 
        self.setWindowTitle('Simple menu')
        #show the application
        self.show()
        #close the UI class
        
if __name__ == '__main__':
    #create the application 
    app = QApplication(sys.argv)
    #use the UI with new  class
    ex = Example()
    #run the UI 
    sys.exit(app.exec_())

Monday, November 19, 2018

Using Google Classroom API with python.

Today I read and test Google API with the Python programming language.
You can find a good example here.
The example shows how to read with Google Classroom API, v1.
This example can be used as a default example if you want to use googlescopes.
The Google documentation tells us:
This document lists the OAuth 2.0 scopes that you might need to request to access Google APIs, depending on the level of access you need. Sensitive scopes require review by Google and have a sensitive indicator on the Google Cloud Platform (GCP) Console's OAuth consent screen configuration page. Many scopes overlap, so it's best to use a scope that isn't sensitive. For information about each method's scope requirements, see the individual API documentation.
The script use credentials.json file created by the Google project in the folder with the python script.
The script creates automatically when the authorization flow completes a token.json file.
The control of the project can be used with the Google Cloud Console.
The result of the example script can be seen in the next image:

Friday, November 16, 2018

Python Qt5 : setStyleSheet example.

Today I will show you how to style the PyQt5 widgets and create a good looking application interface.
The main goal of this tutorial is to see where you can use the style issue.
I used just one edit and one button to have a simple example.
The result of my example is this:

The example start with a simple application with QPushButton, QLineEdit.
Is more simple to use a class for the button because we need to create a different style for each action: enterEvent or leaveEvent and so on.
You can see I used QFont to change the font from button.
This class is named Push_button and will be used like any QPushButton from default PyQt5 examples.
We can do this for any widget and change it with setStyleSheet.
Another part of the code is for QLineEdit.
This can be changed easily with setStyleSheet, first with the default of this and make other changes when you need.
The source code has an QGridLayout to help us to align the widgets.
Let's see the source code:
from PyQt5 import QtWidgets, QtGui, QtCore
from PyQt5.QtCore import pyqtSignal

font_button = QtGui.QFont()
font_button.setFamily("Corbel")
font_button.setPointSize(10)
font_button.setWeight(100)

class Push_button(QtWidgets.QPushButton):
    
    def __init__(self, parent=None):
        super(Push_button, self).__init__(parent)
        self.setMouseTracking(True)
        self.setStyleSheet("margin: 1px; padding: 10px; \
      background-color: \
                           rgba(255,255,0,255); \
                           color: rgba(0,0,0,255); \
                           border-style: solid; \
                           border-radius: 4px; border-width: 3px; \
                           border-color: rgba(0,0,0,255);")

    def enterEvent(self, event):
        if self.isEnabled() is True:
            self.setStyleSheet("margin: 10px; padding: 10px; \
          background-color: \
                               rgba(255,255,0,255); \
                               color: rgba(0,0,10,255); \
                               border-style: solid; \
                               border-radius: 8px; \
                               border-width: 1px; \
                               border-color: \
                               rgba(0,0,100,255);")
        if self.isEnabled() is False:
            self.setStyleSheet("margin: 10px; padding: 10px; \
          background-color: \
                               rgba(255,255,0,255); \
                               color: rgba(0,0,10,255); \
                               border-style: solid; \
                               border-radius: 8px; \
                               border-width: 1px; \
                               border-color: \
                               rgba(0,0,100,255);")

    def leaveEvent(self, event):
        self.setStyleSheet("margin: 10px; padding: 10px; \
                           background-color: rgba(0,0,0,100); \
                           color: rgba(0,0,255,255); \
                           border-style: solid; \
                           border-radius: 8px; border-width: 1px; \
                           border-color: rgba(0,50,100,255);")


class QthreadApp(QtWidgets.QWidget):
    sig = pyqtSignal(str)
    def __init__(self, parent=None):
        QtWidgets.QWidget.__init__(self, parent)
        self.setWindowTitle("PyQt5 style application")
        self.setWindowIcon(QtGui.QIcon("icon.png"))
        self.setMinimumWidth(resolution.width() / 3)
        self.setMinimumHeight(resolution.height() / 2)
        self.setStyleSheet("QWidget { \
                           background-color: rgba(0,0,100,250);} \
                           QScrollBar:horizontal {width: 1px; \
                           height: 1px; \
                           background-color: rgba(0,100,255,0);} \
                           QScrollBar:vertical {width: 1px; \
                           height: 10px; \
                           background-color: rgba(0,41,59,255);}")
        self.linef = QtWidgets.QLineEdit(self)
        self.linef.setPlaceholderText("Input text ...")
        self.linef.setStyleSheet("margin: 10px; padding: 10px; \
                                 background-color: \
                                 rgba(0,0,0,255);\
                                 color: rgba(255,0,0,255); \
                                 border-style: solid; \
                                 border-radius: 15px; \
                                 border-width: 1px; \
                                 border-color: \
                                 rgba(255,255,255,255);")
        self.my_button = Push_button(self)
        self.my_button.setText("Blue")
        self.my_button.setFixedWidth(72)
        self.my_button.setFont(font_button)
        self.my_grid = QtWidgets.QGridLayout()
        self.my_grid.addWidget(self.linef, 0, 0, 1, 220)
        self.my_grid.addWidget(self.my_button, 0, 220, 1, 1)
        self.my_grid.setContentsMargins(8, 8, 8, 8)
        self.setLayout(self.my_grid)

if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)
    desktop = QtWidgets.QApplication.desktop()
    resolution = desktop.availableGeometry()
    myapp = QthreadApp()
    myapp.setWindowOpacity(0.95)
    myapp.show()
    myapp.move(resolution.center() - myapp.rect().center())
    sys.exit(app.exec_())
else:
    desktop = QtWidgets.QApplication.desktop()
    resolution = desktop.availableGeometry()

Monday, November 12, 2018

Python Qt5 : QCalendarWidget example.

This tutorial is about QCalendarWidget.
Use a default application and add this widget.
You can change and get the date from the widget calendar like any widget.
The result of this source code is this result:

This is the source code for QCalendarWidget example:
import sys
from PyQt5 import *
from PyQt5.QtWidgets import QApplication, QCalendarWidget, QWidget, QLabel
from PyQt5.QtCore import *
from PyQt5.QtGui import *

class Example(QWidget):
   def __init__(self):
      super(Example, self).__init__()
      self.initUI()
   def initUI(self):
      my_calendar = QCalendarWidget(self)
      my_calendar.setGridVisible(True)
      my_calendar.move(10, 20)
      my_calendar.clicked[QDate].connect(self.show_date)
      self.my_label = QLabel(self)
      date = my_calendar.selectedDate()
      self.my_label.setText(date.toString())
      self.my_label.move(10, 220)
      self.setGeometry(100,100,320,270)
      self.setWindowTitle('Calendar')
      self.show()
   def show_date(self, date):
      self.my_label.setText(date.toString())

def main():
   app = QApplication(sys.argv)
   ex = Example()
   sys.exit(app.exec_())
if __name__ == '__main__':
   main()

Saturday, November 10, 2018

Python Qt5 : QTabWidget example.

Today I test the QTabWidget with an simple example.
The source code uses the QTabWidget and create two Tab: FirstTab and TabTwo.
I add for each tab two labels: tab_one_label_one, tab_one_label_two,tab_two_label_one and tab_two_label_two.
For layouts, I used: vboxLayout with first_layout and second_layout.
The result of my running code is this:

The rest of the source code is simple:
import sys
from PyQt5.QtGui import QIcon
from PyQt5.QtWidgets import QDialog, QApplication, QWidget
from PyQt5.QtWidgets import QVBoxLayout, QTabWidget, QLabel

class TabDialog(QDialog):
    def __init__(self):
        super().__init__()

        self.setWindowTitle("Tab Widget Application")
        self.setWindowIcon(QIcon("icon.png"))

        tabwidget = QTabWidget()
        tabwidget.addTab(FirstTab(), "First Tab")
        tabwidget.addTab(TabTwo(), "Second Tab")

        vboxLayout = QVBoxLayout()
        vboxLayout.addWidget(tabwidget)

        self.setLayout(vboxLayout)

class FirstTab(QWidget):
    def __init__(self):
        super().__init__()
        tab_one_label_one = QLabel("tab_one_label_one")
        tab_one_label_two = QLabel("tab_one_label_two")
        
        first_layout = QVBoxLayout()
        first_layout.addWidget(tab_one_label_one)
        first_layout.addWidget(tab_one_label_two)
        self.setLayout(first_layout)

class TabTwo(QWidget):
    def __init__(self):
        super().__init__()
        tab_two_label_one = QLabel("tab_two_label_one")
        tab_two_label_two = QLabel("tab_two_label_two")
        
        second_layout = QVBoxLayout()
        second_layout.addWidget(tab_two_label_one)
        second_layout.addWidget(tab_two_label_two)
        self.setLayout(second_layout)

if __name__ == "__main__":
    app = QApplication(sys.argv)
    tabdialog = TabDialog()
    tabdialog.show()
    app.exec()