Search code examples
tkinterpyqtcomparisonwxpythonpyside

What is the differences between Tkinter, WxWidgets and PyQt, and PySide?


I was wondering what are the differences among the GUI toolkits such as tkinter, wxWidgets and PyQt, PySide. They produces similar widgets like list boxes, text engines, and buttons, check boxes, etc. I was confused by the similar engines there.

I am using Tkinter right now, and I found that it’s lacking of complex widgets, like the using of table. I have tried to use the tree view before, but I found out that there’s a widget called QTable something in PyQt and PySide.

I was confused by those names and different usages, especially I cannot distinguish PyQt and Pyside.

Oh, furthermore, I was using Python 3.9 and running on Ubuntu 22.04.


Solution

  • First thing first, there are actually no pure Python GUI toolkit in the Python language. All of the mentioned toolkits are bindings. Let me talk about why.

    Tkinter

    Tkinter, from Python version 2 or earlier, is the only standard GUI (Graphical User Interface) library in the Python programming language. It is a GUI toolkit that it needs not to install via pip or conda or some package manager, in Python (however, if you want to get some good or call directly to the Tcl, you may install it from apt get or https://www.tcl.tk/software/tcltk/, etc.). Its the wrapper of the Tk GUI toolkit, inside the Tcl language.

    Two of the GUI package available in the PyPI as I have known so far, which are the PySimplyGUI and CustomTkinter is based on tkinter, but not developing a GUI library from scratch.

    While Tkinter was complained about its old-styled interface and buggy old- and slow-updating, it still has the following advantages to "survive" in the GUI developing world:

    • Tkinter is a direct, standard library for the Python language. That means no installation is required and that's a huge convenience to the enthusiast programmers and coding kids who haven't set up the $PATH correctly or doesn't know how to use pip or conda or PyQt5 or something else.

    • Secondly, Tkinter is complained about its old-styled interface. In fact, as you might know (because you claims that you're a Tkinter user), there's some module called ttk and its the renew version of the tk.widgets. That's improving its styling configuration and add few new and modern widgets inside it (for example, ttk.Notebook, ttk.ComboBox, etc.)

    • Thirdly, Tkinter is well-known for its simplicity and the ease of learning it. The learning graph of Tkinter is not steep, and its straightforward so that you can handle it very fast.

    wxWidgets

    wxWidgets is a GUI toolkit that wraps the C or C++ GUI framework. It contains numeral advanced widgets such as printing dialogs and font dialogs (however, in Tkinter 8.7 it starts supporting the native font dialog.)

    One of the shining point of wxWidgets is its GUI designer, as known as the WxFormBuilder as well as WxWidgets GUI Designer.

    Qt

    GUI toolkit such as Tkinter, ... PyQt and PySide

    Starting from 1995, Qt become the biggest market for the application development framework and has the largest range and wide of user (developer).

    Oh yeah, one thing I want to correct you. As a Qt user, I want to talk about that Qt is not just a GUI toolkit, although the most famous part of Qt is its GUI building. Qt is an application development framework. In here, you'll probably need no modules but Qt to develop an app, even a super-app. Not only GUI and its builder, Qt Creator, but Qt supports large range of application development stuff. It supports web engine, text editor, backend threading, XML processing and even PDF processing or Image converting using QImage, QPixmap or <QtOpenGL>. You can integrate the Qt with other modules such as OpenCV` also.

    Both PyQt and PySide are the Python binding of the C++ Qt. Both of them are base on a source code called qtbase. However, here's the differences, refer to https://www.pythonguis.com/faq/pyqt5-vs-pyside2/:

    • PyQt uses the General Public License version 2 (GPL2), or a commercial license if you want to use PyQt in commercial activities and publish it to the public. On the other hand, PySide uses the Lesser General Public License version 3.0 (LGPL3).

    • When you calling to QApplication, PyQt5 or PyQt6 must fill in a list of string, usually sys.argv. However, PySide does not require user to do so.

    • PyQt uses PyQt5.QtCore.pyqtSignal and pyqtSlot. However, PySide uses PySide2.QtCore.Signal and Slot. But there attributes and initializing method, as well as the decorators are kept the same.

    • Overall PyQt and PySide are 99.999% similar.

    Examples

    It seems that there's no table control in the Tkinter framework, neither Tcl/Tk nor Python tkinter.

    Regard to your example, its a code written in Qt, in both C++ and Python.

    Our result:

    rst

    Using C++ Qt

    #include <QApplication>
    #include <QWidget>
    #include <QTableWidget>
    
    
    class MainWindow : public QMainWindow
    {
        public:
            MainWindow::MainWindow(QWidget* parent = nullptr)
                : QMainWindow(parent)
            {
                m_tableWidget = new QTableWidget(this);
                m_tableWidget->setRowCount(10);
                m_tableWidget->setColumnCount(5);
                setCentralWidget(m_tableWidget);
            }
    
        private:
            QTableWidget* m_tableWidget;
    };
    
    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
        MainWindow w;
        w.show();
        return a.exec();
    }
    
    

    Using Python PyQt/PySide (actually you can replace everything but changing the PyQt5 to PySide2

    from PyQt5.QtCore import *
    from PyQt5.QtWidgets import *
    from PyQt5.QtGui import *
    import sys
    
    class MainWindow(QMainWindow):
        def __init__(self, parent=None):
            super().__init__(parent)
            
            self.__table_widget = QTableWidget(self)
            self.__table_widget.setRowCount(10)
            self.__table_widget.setColumnCount(5)
            self.setCentralWidget(self.__table_widget)
    
    if __name__ == "__main__":
        app = QApplication(sys.argv)
        mw = MainWindow()
        mw.show()
        sys.exit(app.exec())