用 Python 和 C++ 创建 Qt 程序的简单对比

假设要做一个简单的小窗口(如下图所示),PyQt 和 C++ 要用多少代码可以完成呢?

用 Python 和 C++ 创建 Qt 程序的简单对比_第1张图片
效果图

注:本文内容较多(主要是 C++ 的部分),若有必要请直接跳到最后看结论。

一、 C++ 版本

除了最基础的 pro 文件之外,我一共创建了 5 个文件:

  1. customlabel.h
  2. customlabel.cpp (处理标签Label的右键响应,以及其菜单)
  3. mainform.h
  4. mainform.cpp (主界面窗口)
  5. main.cpp (主程序入口)

以下这 5 个文件的内容都是完整版,可以直接复制过去。

1. customlabel.h

一个可以响应鼠标右键点击的标签。

#ifndef CUSTOMLABEL_H
#define CUSTOMLABEL_H

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

/* ------------------
 * QWidgetAction
 * 这东西可以把输入框显示在菜单项上
 * ------------------*/
class CustomWidgetAction: public QWidgetAction
{
    Q_OBJECT
public:
    explicit CustomWidgetAction(QWidget *parent);
    QLineEdit * editline;
    QVBoxLayout * vlayout;
    QWidget * widget;
    QWidget * createWidget(QWidget *w) override;
};


/* ------------------
 * 可以用右键点击的标签,拥有自己的右键菜单
 * ------------------*/
class CustomLabel : public QLabel
{
    Q_OBJECT
public:
    CustomLabel(QString s);
    QMenu * menu;
    QAction * nmaction;
    CustomWidgetAction * waction;
    void mousePressEvent(QMouseEvent *e) override;
};

#endif // CUSTOMLABEL_H

2. customlabel.cpp

#include "customlabel.h"
#include 

CustomWidgetAction::CustomWidgetAction(QWidget *parent)
    :QWidgetAction(parent)
{
    editline = new QLineEdit(tr("这里可以显示中文"));
    vlayout = new QVBoxLayout();
    vlayout->addWidget(editline);
    widget = new QWidget();
    widget->setLayout(vlayout);
}

QWidget* CustomWidgetAction::createWidget(QWidget *w)
{   // 必须要有这个函数,用来获得需要显示的控件
    widget->setParent(w);
    editline->setFocus();
    return widget;
}

CustomLabel::CustomLabel(QString s):QLabel(s)
{
    waction = new CustomWidgetAction(this);
    menu = new QMenu(this);
    menu->addAction(waction);
}

void CustomLabel::mousePressEvent(QMouseEvent* e)
{
    if (e->button() == Qt::RightButton)
        menu->exec(QCursor::pos());    // 当点击右键时显示菜单
}

3. mainform.h

主窗口。

#ifndef MAINFORM_H
#define MAINFORM_H

#include 
#include 
#include 
#include 
#include "customlabel.h"

class MainForm : public QDialog
{
    Q_OBJECT
public:
    explicit MainForm(QWidget *parent = nullptr);

    QPushButton * button;
    QLineEdit * editbox;
    CustomLabel * label;
    QVBoxLayout * vlayout;
};

#endif // MAINFORM_H

4. mainform.cpp

#include "mainform.h"

MainForm::MainForm(QWidget *parent) : QDialog(parent)
{
    resize(320, 240);
    setWindowTitle("Test QWidgetAction");

    editbox = new QLineEdit(tr("This box can input any languages."));
    label = new CustomLabel(tr("Right click on me to show popup menu."));
    button = new QPushButton(tr("Close"));
    vlayout = new QVBoxLayout(this);
    vlayout->addWidget(editbox);
    vlayout->addWidget(label);
    vlayout->addWidget(button);

    connect(button, SIGNAL(clicked()), this, SLOT(close()));
}

5. main.cpp

程序入口。

#include "mainform.h"
#include 

int main(int argc, char* argv[])
{   // Qt 程序入口
    QApplication app(argc, argv);
    MainForm form;
    form.show();

    return app.exec();
}

以上是 C++ 版 Qt 的代码,洋洋洒洒一大篇,虽然很有成就感,但也花费了不少时间。


二、 Python 版本

只用一个文件:

from PyQt5 import QtWidgets, QtGui, QtCore

class MyWidgetAction(QtWidgets.QWidgetAction):
    def __init__(self, parent):
        super().__init__(parent)
        self.editbox = QtWidgets.QLineEdit('直接显示中文是没有问题的。')
        self.vlayout = QtWidgets.QVBoxLayout()
        self.vlayout.addWidget(self.editbox)
        self.widget = QtWidgets.QWidget()
        self.widget.setLayout(self.vlayout)

    def createWidget(self, parent):
        self.widget.setParent(parent)
        self.editbox.setFocus()
        return self.widget

class MyLabel(QtWidgets.QLabel):
    def __init__(self):
        super().__init__()
        self.setText('Right click on me to show popup menu.')
        self.waction = MyWidgetAction(self)
        self.menu = QtWidgets.QMenu()
        self.menu.addAction(self.waction)

    def mousePressEvent(self, e):
        if e.button() == QtCore.Qt.RightButton:
            self.menu.exec_(QtGui.QCursor.pos())

app = QtWidgets.QApplication([])
dlg = QtWidgets.QDialog()
txt = QtWidgets.QLineEdit('This box can input CJK characters.')
lbl = MyLabel()
btn = QtWidgets.QPushButton('Close')
btn.clicked.connect(dlg.close)
vbl = QtWidgets.QVBoxLayout(dlg)
vbl.addWidget(txt)
vbl.addWidget(lbl)
vbl.addWidget(btn)
dlg.resize(320, 240)
dlg.show()
app.exec_()

不得不说 Python 这东西真是方便,只要一个文件、不到 50 行代码就能实现!


你更喜欢哪一种?


这只是个小应用,Python 的开发效率明显高出不少。不过随着项目越来越庞大,Python 作为动态语言的弊端也逐渐显现,复杂场景中的错误可能会变得不可控。控制台上出错顶多抛出一个异常,使用者还能现场纠错,但 GUI 程序可是会闪退的啊!不过想想 C++ 应用也会毫无预兆地 crash,我不禁又陷入了沉思……

用 Python 和 C++ 创建 Qt 程序的简单对比_第2张图片
图文无关

(完)

你可能感兴趣的:(用 Python 和 C++ 创建 Qt 程序的简单对比)