Qt 程序間通訊,Qt子程序嵌入主程序

一字千金發表於2024-06-03
本程式實現的功能是將子程序嵌入主程序,透過程序間通訊將子程序的視窗控制代碼傳送給服務端,然後服務端將子程序視窗嵌入主程序;

服務端主程序

#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include<QLocalServer>
#include <QMainWindow>
#include<QLocalSocket>
#include"ui_mainwindow.h"
namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();
    void ProcessData(QString strData);
public slots:
    void on_newConnection();
    void on_socketReadyRead(QLocalSocket *socketTmp );
signals:
    void SignalError(int type, QString strContent);
private:
    Ui::MainWindow ui;
    QLocalServer server;

};



#endif // MAINWINDOW_H


//服務端
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include<QProcess>
#include<QDir>
#include<QMessageBox>
#include<QWindow>
MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent)
{
    ui.setupUi(this);

       server.removeServer("DragDrop");// we have to remove the name,otherwise when it will be ocupped when opened in the secocend time  
       bool flag=  server.listen("DragDrop"); // 繫結名為"MyServer"的服務
        if(!flag) {
               QMessageBox::information(this, u8"提示", server.errorString());
           }

        connect(&server, &QLocalServer::newConnection, this, &MainWindow::on_newConnection);

}

MainWindow::~MainWindow()
{

}

void MainWindow::ProcessData(QString strData)
{
    WId childWnd = atoi(strData.toStdString().c_str());
    QWidget* pSubWidget=NULL;
        if (NULL == pSubWidget)
        {
            pSubWidget = QWidget::createWindowContainer(QWindow::fromWinId(childWnd),ui.centralWidget);
        }
        pSubWidget->setParent(ui.centralWidget);
        pSubWidget->move(0,0);
        pSubWidget->setGeometry(0,0,800,600);
        pSubWidget->show();
}
void MainWindow::on_newConnection()
{
    // 判斷是否存在新的socket連線
       if(server.hasPendingConnections())
       {
           // 獲取套接字物件
           QLocalSocket *socketTmp = server.nextPendingConnection();

           // 套接字文字新增到下拉選單中並在介面做出連線提示
           connect(socketTmp, &QLocalSocket::readyRead, this, [=](){on_socketReadyRead(socketTmp);});
       }

}

void MainWindow::on_socketReadyRead(QLocalSocket *socketTmp)
{
    if(socketTmp!=NULL)
    {
        QString strCotent=socketTmp->readAll();
        ProcessData(strCotent);
    }
}

客戶端子程序

#ifndef CHILDWINDOW_H
#define CHILDWINDOW_H
#include<QDragEnterEvent>
#include<QDragLeaveEvent>
#include <QDropEvent>
#include <QMimeData>
#include <QMainWindow>
#include<QString>
#include"ui_childwindow.h"
#include<QLocalSocket>
namespace Ui {
class ChildWindow;
}

class ChildWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit ChildWindow(QWidget *parent = 0);
    ~ChildWindow();
    void dragEnterEvent(QDragEnterEvent *event);
        void dropEvent(QDropEvent *event);
        void dragLeaveEvent(QDragLeaveEvent *event);
signals:
    void SignalError(int type, QString strContent);
private:
    Ui::ChildWindow ui;
      QLocalSocket socket;
};

#endif // CHILDWINDOW_H

#include "childwindow.h"
#include "ui_childwindow.h"
#include<QFileInfo>
ChildWindow::ChildWindow(QWidget *parent) :
    QMainWindow(parent)
{
    ui.setupUi(this);
    setWindowFlags(Qt::CustomizeWindowHint |Qt::FramelessWindowHint);

        socket.connectToServer("DragDrop");
       if(socket.waitForConnected())
       {
           if(socket.open(QIODevice::ReadWrite))
           {
                socket.write(QString::number(this->winId()).toStdString().c_str());
           }

       }

}

ChildWindow::~ChildWindow()
{

}
void ChildWindow::dragEnterEvent(QDragEnterEvent *event)
{
    QStringList allowedExtensions;
    allowedExtensions << "jpg" << "jpeg" << "png" << "tiff"<<"JPG"<<"JPEG"<<"PNG"<<"TIFF";
    const QMimeData *mimeData = event->mimeData();
    int CountUnsurport = 0;
    QStringList listPath;
    if (mimeData->hasUrls())
    {
        QList<QUrl> urls = mimeData->urls();
        for (int i = 0; i < urls.size(); i++)
        {
            QString filePath = urls.at(i).toLocalFile(); // 通常只處理第一個url
            QFileInfo fileinfo(filePath);
            if (fileinfo.isDir())
            {
                listPath.push_back(filePath);
            }
            else
            {
                QString extension = fileinfo.suffix();
                if (allowedExtensions.contains(extension))
                {
                    listPath.push_back(filePath);
                }
                else
                {

                    CountUnsurport++;
                }
            }
        }
    }
    if (CountUnsurport>0)
    {
        event->ignore(); // 接受拖動
    }
    else
    {
        event->acceptProposedAction(); // 接受拖動
        ui.widget->hide();
        ui.widgetRelease->show();
        ui.widgetAddPic->setStyleSheet(QLatin1String("\n"
            "QWidget#widgetAddPic\n"
            "{\n"
            "    border: 1px dashed rgba(255, 255, 255, 0.3);\n"
            "    border-radius: 4px;\n"
            "    background:rgba(32, 128, 247, 0.16);\n"
            "}"));
    }
}

void ChildWindow::dropEvent(QDropEvent *event)
{
    // 允許的副檔名列表
    ui.widget->show();
    ui.widgetPic->show();
    ui.widgetRelease->hide();
    ui.widgetAddPic->setStyleSheet(QLatin1String("\n"
        "QWidget#widgetAddPic\n"
        "{\n"
        "    border: 1px dashed rgba(255, 255, 255, 0.3);\n"
        "    border-radius: 4px;\n"
        "    background: rgb(40, 40, 41);\n"
        "}"));
    QStringList allowedExtensions;
    allowedExtensions << "jpg" << "jpeg" << "png" << "tiff" << "JPG" << "JPEG" << "PNG" << "TIFF";
    const QMimeData *mimeData = event->mimeData();
    int CountUnsurport = 0;
    QStringList listPath;
    if (mimeData->hasUrls())
    {
        QList<QUrl> urls = mimeData->urls();
        for (int i = 0; i < urls.size(); i++)
        {
            QString filePath = urls.at(i).toLocalFile(); // 通常只處理第一個url
            QFileInfo fileinfo(filePath);
            if (fileinfo.isDir())
            {
                listPath.push_back(filePath);
            }
            else
            {
                QString extension = fileinfo.suffix();
                if (allowedExtensions.contains(extension))
                {
                    listPath.push_back(filePath);
                }
                else
                {

                    CountUnsurport++;
                }
            }
        }
    }
    if (CountUnsurport>0)
    {
        emit SignalError(-3, QString("有%1個檔案不符合格式要求").arg(CountUnsurport));
        return;
    }
    //AddSelectedFile(listPath);
}

void ChildWindow::dragLeaveEvent(QDragLeaveEvent *event)
{
    ui.widget->show();
    ui.widgetRelease->hide();
    ui.widgetAddPic->setStyleSheet(QLatin1String("\n"
        "QWidget#widgetAddPic\n"
        "{\n"
        "    border: 1px dashed rgba(255, 255, 255, 0.3);\n"
        "    border-radius: 4px;\n"
        "    background: rgb(40, 40, 41);\n"
        "}"));
}

相關文章