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

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

效果图

注:本文内容较多(主要是 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 <QMenu>
#include <QLabel>
#include <QLineEdit>
#include <QAction>
#include <QWidget>
#include <QVBoxLayout>
#include <QWidgetAction>
#include <QMouseEvent>
#include <QString>

/* ------------------
 * 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 <QCursor>

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 <QDialog>
#include <QPushButton>
#include <QVBoxLayout>
#include <QLineEdit>
#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 <QApplication>

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,我不禁又陷入了沉思……

图文无关

(完)

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,132评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,802评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,566评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,858评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,867评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,695评论 1 282
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,064评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,705评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,915评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,677评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,796评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,432评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,041评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,992评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,223评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,185评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,535评论 2 343