一、先说问题答案
Q_OBJECT 不用放在.cpp文件中编译需要放在.h里面编译。
二、最近要将C#项目搬迁到linux上,就开始看qt,一个小问题都能卡几天难受啊。贴一下第一个qt测试程序:
这是用来给qt和前端结合使用的。
这个资源是必须的:
在这里插入图片描述

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QtWebEngineWidgets/QtWebEngineWidgets>
#include <QtWebChannel/qwebchannel.h>

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

    QWebEngineView* m_view;
    QWebChannel* m_channel;

private:
    Ui::MainWindow *ui;
};


class MyClassOne : public QObject
{
    //Q_OBJECT一定要加
    Q_OBJECT
public slots:
    void add(){
        QMessageBox::information(NULL, "class1", "class1");
    }

    void showMsgBox(const QString& message) {
        qDebug() << "Received message:" << message;
    }
};

class MyClassTwo : public QObject
{
    Q_OBJECT
public slots:
    void add(){
        QMessageBox::information(NULL, "class2", "class2");
    }
};

#endif // MAINWINDOW_H

main.cpp

#include "mainwindow.h"

#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
    w.show();
    return a.exec();
}

mainwindow.cpp

#include "mainwindow.h"
#include "./ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    m_view = new QWebEngineView(this);
    setCentralWidget(m_view);
    m_channel = new QWebChannel(this);
    MyClassOne *myclassone = new MyClassOne();
    MyClassTwo *myclasstwo = new MyClassTwo();
    m_channel->registerObject(QStringLiteral("myclassone"), (QObject*)myclassone);
    m_channel->registerObject(QStringLiteral("myclasstwo"), (QObject*)myclasstwo);

    m_view->page()->setWebChannel(m_channel);

    QString htmlPath = "D://Desktop/calculator_h5/calculator.html";
    m_view->page()->load(htmlPath);

    connect(m_view->page(), &QWebEnginePage::loadFinished, this, [this]() {
        // 执行 JavaScript 代码
        m_view->page()->runJavaScript("js_func()");
    });

//    QMessageBox::information(nullptr, "title", "open the door");
}

MainWindow::~MainWindow()
{
    delete ui;
}

CMakeLists.txt

cmake_minimum_required(VERSION 3.5)

project(testQWebEngine VERSION 0.1 LANGUAGES CXX)

set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Widgets)
find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Widgets)
find_package(Qt5 REQUIRED COMPONENTS WebEngineWidgets)
find_package(Qt5 REQUIRED COMPONENTS Core)
find_package(Qt5 REQUIRED COMPONENTS WebChannel)


set(PROJECT_SOURCES
        main.cpp
        mainwindow.cpp
        mainwindow.h
        mainwindow.ui
)


if(${QT_VERSION_MAJOR} GREATER_EQUAL 6)
    qt_add_executable(testQWebEngine
        MANUAL_FINALIZATION
        ${PROJECT_SOURCES}
    )
# Define target properties for Android with Qt 6 as:
#    set_property(TARGET testQWebEngine APPEND PROPERTY QT_ANDROID_PACKAGE_SOURCE_DIR
#                 ${CMAKE_CURRENT_SOURCE_DIR}/android)
# For more information, see https://doc.qt.io/qt-6/qt-add-executable.html#target-creation
else()
    if(ANDROID)
        add_library(testQWebEngine SHARED
            ${PROJECT_SOURCES}
        )
# Define properties for Android with Qt 5 after find_package() calls as:
#    set(ANDROID_PACKAGE_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/android")
    else()
        add_executable(testQWebEngine
            ${PROJECT_SOURCES}
        )
    endif()
endif()

target_link_libraries(testQWebEngine PRIVATE Qt${QT_VERSION_MAJOR}::Widgets)
target_link_libraries(testQWebEngine PRIVATE Qt5::WebEngineWidgets)
target_link_libraries(testQWebEngine PRIVATE Qt5::Core)

# Qt for iOS sets MACOSX_BUNDLE_GUI_IDENTIFIER automatically since Qt 6.1.
# If you are developing for iOS or macOS you should consider setting an
# explicit, fixed bundle identifier manually though.
if(${QT_VERSION} VERSION_LESS 6.1.0)
  set(BUNDLE_ID_OPTION MACOSX_BUNDLE_GUI_IDENTIFIER com.example.testQWebEngine)
endif()
set_target_properties(testQWebEngine PROPERTIES
    ${BUNDLE_ID_OPTION}
    MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION}
    MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}
    MACOSX_BUNDLE TRUE
    WIN32_EXECUTABLE TRUE
)

include(GNUInstallDirs)
install(TARGETS testQWebEngine
    BUNDLE DESTINATION .
    LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
    RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
)

if(QT_VERSION_MAJOR EQUAL 6)
    qt_finalize_executable(testQWebEngine)
endif()

html

<!DOCTYPE html>
<h1>Hello,world!</h1>
<head>
  <title></title>
</head>
<body>
	<div>
		<input value="class1" type="button" onclick="button_1();" />
		<input value="class2" type="button" onclick="button_2();" />
	</div>
	
  <script src="./qwebchannel.js"></script> 
  <script type="text/javascript">
    var myclass;
	var showMsgBox;
	// 在页面加载完成后执行初始化
	document.addEventListener("DOMContentLoaded", function() {
	  new QWebChannel(qt.webChannelTransport, function(channel) {
		one = channel.objects.myclassone;
		two = channel.objects.myclasstwo;
	  });
	});
    
    function button_1() {
	  one.add();
	}
	
	function button_2() {
	  two.add();
	}

	function js_func(){
		alert('这是一个弹窗消息');
	}
  </script>
</body>
</html>

js在安装qt的目录下,我的在这里D:\Qt\Examples\Qt-5.15.2\webchannel\shared

网上写个测试例子都那么麻烦,简单点不好吗,哈哈我写的最简单。

Logo

鸿蒙生态一站式服务平台。

更多推荐