Compare commits

...

2 Commits

Author SHA1 Message Date
055116147e can run 2025-08-31 00:12:26 +08:00
fef67a02c9 Init crash 2025-08-31 00:03:00 +08:00
5 changed files with 130 additions and 0 deletions

1
.gitignore vendored
View File

@@ -67,4 +67,5 @@ compile_commands.json
CTestTestfile.cmake
_deps
CMakeUserPresets.json
/build

38
CMakeLists.txt Normal file
View File

@@ -0,0 +1,38 @@
cmake_minimum_required(VERSION 3.10)
project(MotifQtApp LANGUAGES CXX)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
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(Qt5 COMPONENTS Widgets REQUIRED)
# Motif
find_package(X11 REQUIRED)
find_library(MOTIF_LIB Xm)
message(STATUS
"MOTIF_LIBRARIES = ${MOTIF_LIBRARIES}\n"
"X11_LIBRARIES = ${X11_LIBRARIES}\n"
"X11_Xt_LIB = ${X11_Xt_LIB}"
)
# 源文件
set(SOURCES
motif_app.cpp
qt_dialog.cpp
qt_dialog.h
)
# 可执行文件
add_executable(MotifQtApp ${SOURCES})
# 链接库
target_link_libraries(MotifQtApp PRIVATE Qt5::Widgets ${MOTIF_LIB} X11::X11 ${X11_Xt_LIB})
target_include_directories(MotifQtApp PRIVATE ${X11_INCLUDE_DIR})

70
motif_app.cpp Normal file
View File

@@ -0,0 +1,70 @@
#include <QApplication>
#include <QTimer>
#include "qt_dialog.h"
// Qt 头文件必须在 Motif/X11 之前
#include <X11/Intrinsic.h>
#include <Xm/Xm.h>
#include <Xm/PushB.h>
#include <unistd.h> // for usleep
// 全局 Qt 应用和对话框指针
QApplication *g_app = nullptr;
// 打开 Qt 对话框
void openQtDialog(Widget w, XtPointer client_data, XtPointer call_data)
{
auto dialog = new QtDialog();
dialog->setAttribute(Qt::WA_DeleteOnClose); // 关闭时自动删除
dialog->show(); // 非阻塞显示
}
// Motif 主循环中处理 Qt 事件
void processQtEvents()
{
if (g_app)
{
g_app->processEvents();
}
}
int main(int argc, char **argv)
{
XtAppContext app_context;
Widget toplevel, button;
// 创建 QApplication必须在 Qt 头文件之后)
g_app = new QApplication(argc, nullptr);
// 创建 Motif 主窗口
toplevel = XtVaAppInitialize(&app_context, "MotifQtApp", NULL, 0,
&argc, argv, NULL, NULL);
button = XtVaCreateManagedWidget("Open Qt Dialog",
xmPushButtonWidgetClass,
toplevel, NULL);
XtAddCallback(button, XmNactivateCallback, openQtDialog, NULL);
XtRealizeWidget(toplevel);
XEvent event;
while (1)
{
while (XtAppPending(app_context))
{
XtAppNextEvent(app_context, &event);
XtDispatchEvent(&event);
}
// 每次空闲处理 Qt 事件
processQtEvents();
// 避免 CPU 空转
usleep(1000);
}
// 清理(一般不会执行到这里)
delete g_app;
return 0;
}

13
qt_dialog.cpp Normal file
View File

@@ -0,0 +1,13 @@
#include "qt_dialog.h"
#include <QLabel>
#include <QVBoxLayout>
QtDialog::QtDialog(QWidget* parent)
: QDialog(parent)
{
setWindowTitle("Non-blocking Qt Dialog");
QVBoxLayout* layout = new QVBoxLayout(this);
QLabel* label = new QLabel("Hello from Qt (non-blocking)!", this);
layout->addWidget(label);
setLayout(layout);
}

8
qt_dialog.h Normal file
View File

@@ -0,0 +1,8 @@
#pragma once
#include <QDialog>
class QtDialog : public QDialog {
Q_OBJECT
public:
QtDialog(QWidget* parent = nullptr);
};