From ec418a5b20377b815913a2fd37d50f0ea81c947a Mon Sep 17 00:00:00 2001 From: Mathieu L Bouchard <matju@artengine.ca> Date: Sun, 3 Aug 2014 00:30:04 -0400 Subject: [PATCH] added dummy Qt window with three menu items --- pd/src/g_canvas.h | 6 ++++ pd/src/g_qt.cpp | 68 ++++++++++++++++++++++++++++++++++++++++++---- pd/src/g_qt.h | 28 +++++++++++++++++++ pd/src/makefile.in | 4 +-- pd/src/s_inter.c | 18 ++++++++++++ 5 files changed, 117 insertions(+), 7 deletions(-) diff --git a/pd/src/g_canvas.h b/pd/src/g_canvas.h index 3f90b2eae..8e25fefec 100644 --- a/pd/src/g_canvas.h +++ b/pd/src/g_canvas.h @@ -770,6 +770,12 @@ EXTERN void *canvas_undo_set_font(t_canvas *x, int font); /* ------------------------------- */ +/* ---------- interface to Qt (libQt5) with threads -------------------- */ + +void *qt_thread_main (void *); + +/* --------------------------------------------------------------------- */ + #if defined(_LANGUAGE_C_PLUS_PLUS) || defined(__cplusplus) } #endif diff --git a/pd/src/g_qt.cpp b/pd/src/g_qt.cpp index 72ba28b38..f73a75c38 100644 --- a/pd/src/g_qt.cpp +++ b/pd/src/g_qt.cpp @@ -1,17 +1,22 @@ #include <stdio.h> #include <sys/time.h> #include <unistd.h> +#include "m_pd.h" +#include "g_canvas.h" + #include <QtWidgets/QApplication> +#include <QtWidgets/QLabel> +#include <QtWidgets/QMenuBar> +#include <QtWidgets/QMenu> +#include <QtWidgets/QMessageBox> +#include <QtGui/QtGui> #include "g_qt.h" int tv_ms_diff (timeval &a, timeval &b) { - return (a.tv_sec-b.tv_sec)*1000 + (a.tv_usec-b.tv_usec)/1000; + return (a.tv_sec-b.tv_sec)*1000 + (a.tv_usec-b.tv_usec)/1000; } -void qt_thread_main () { - int argc=0; char **argv=0; - //QApplication app(argc,argv); - +static void infinite_loop () { timeval t0,t1; gettimeofday(&t0,0); for (;;) { @@ -20,3 +25,56 @@ void qt_thread_main () { sleep(2); } } + +void *qt_thread_main (void *) { + int argc=0; char **argv=0; + QApplication app(argc,argv); + app.setApplicationName("PureData L2ork for Qt"); + MainWindow mainWin; + mainWin.show(); + app.exec(); + fprintf(stderr,"qt_thread_main EXITING\n"); + return 0; +} + +#define MENUITEM(MENU,ACT,TEXT,FUNC) \ + ACT = new QAction(tr(TEXT), this); \ + connect(ACT, SIGNAL(triggered()), this, SLOT(FUNC)); \ + MENU->addAction(ACT); + +MainWindow::MainWindow () { + QLabel *l = new QLabel("Hello Data Flowers"); + l->setAlignment(Qt::AlignHCenter|Qt::AlignVCenter); + setCentralWidget(l); + + fileMenu = menuBar()->addMenu(tr("&File")); + MENUITEM(fileMenu,quitAct,"Quit",close()); + + editMenu = menuBar()->addMenu(tr("&Edit")); + MENUITEM(editMenu,editModeAct,"&Edit mode",editMode()); + + menuBar()->addSeparator(); + helpMenu = menuBar()->addMenu(tr("&Help")); + MENUITEM(helpMenu,aboutAct,"&About",about()); +} + +void MainWindow::about () { + QMessageBox::about(this, tr("About PureData L2ork"), + tr("<b>PureData</b> is an app whose purpose is to turn bits into potentially different bits.")); +} + +void MainWindow::editMode () { + QMessageBox::about(this, tr("Edit Mode"), + tr("To toggle edit mode, please implement this feature and recompile.")); +} + +bool MainWindow::askQuit () { + return QMessageBox::Ok == QMessageBox::warning(this, tr("Quit"), + tr("This will close Qt but leave Tk windows open. Proceed ?"), QMessageBox::Ok | QMessageBox::Cancel); +} + +//void MainWindow::quit () {if (askQuit()) ...} + +void MainWindow::closeEvent(QCloseEvent *event) { + if (askQuit()) event->accept(); else event->ignore(); +} diff --git a/pd/src/g_qt.h b/pd/src/g_qt.h index 8b1378917..8833327ba 100644 --- a/pd/src/g_qt.h +++ b/pd/src/g_qt.h @@ -1 +1,29 @@ +// this file is for MOC/Qt stuff. +// Do not include in C source. +// the C interface to g_qt.c will be in g_canvas.h. +#include <QtWidgets/QMainWindow> + +class MainWindow : public QMainWindow { + Q_OBJECT +public: + MainWindow(); + bool askQuit(); + void closeEvent(QCloseEvent *event); + + // list of menus + QMenu *fileMenu; + QMenu *editMenu; + QMenu *helpMenu; + + // list of actions connecting menus/buttons to slots + QAction *quitAct; + QAction *editModeAct; + QAction *aboutAct; + +public slots: + // list of functions called by menus or buttons + //void quit (); + void editMode (); + void about (); +}; diff --git a/pd/src/makefile.in b/pd/src/makefile.in index 971b3c4af..047e84429 100644 --- a/pd/src/makefile.in +++ b/pd/src/makefile.in @@ -141,10 +141,10 @@ $(ASIOOBJ): %.o : %.cpp $(CXX) $(CFLAGS) $(INCLUDE) -c -o $(OBJ_DIR)/$*.o $*.cpp ../obj/g_qt.moc.cpp : g_qt.h - $(MOC) $(CPPFLAGS) $(QT_INCLUDE) $< -o ../obj/$@ + $(MOC) $(subst $(CPPFLAGS),-fno-strict-aliasing,) $(QT_INCLUDE) $< -o ../obj/$@ ../obj/g_qt.moc.o : ../obj/g_qt.moc.cpp - $(CXX) $(CFLAGS) $(CXXFLAGS) $(QT_INCLUDE) -c ../obj/g_qt.moc.cpp -o ../obj/g_qt.moc.o + $(CXX) $(CFLAGS) $(CXXFLAGS) $(QT_INCLUDE) -fPIC -c ../obj/g_qt.moc.cpp -o ../obj/g_qt.moc.o ../obj/g_qt.o : g_qt.cpp $(CXX) $(CFLAGS) $(CXXFLAGS) $(QT_INCLUDE) -fPIC -c g_qt.cpp -o ../obj/g_qt.o diff --git a/pd/src/s_inter.c b/pd/src/s_inter.c index d7c0e8e0f..15211fa50 100644 --- a/pd/src/s_inter.c +++ b/pd/src/s_inter.c @@ -114,6 +114,11 @@ static t_binbuf *inbinbuf; static t_socketreceiver *sys_socketreceiver; extern int sys_addhist(int phase); +#ifdef QTGUI +pthread_t sys_thread_main; +pthread_t sys_thread_qt; +#endif + /* ----------- functions for timing, signals, priorities, etc --------- */ #ifdef MSW @@ -889,6 +894,15 @@ static int defaultfontshit[MAXFONTS] = { 24, 15, 28}; #define NDEFAULTFONT (sizeof(defaultfontshit)/sizeof(*defaultfontshit)) + +#ifdef QTGUI +void sys_start_qt () { + sys_thread_main = pthread_self(); + int r = pthread_create(&sys_thread_qt,0,qt_thread_main,0); + if (r) fprintf(stderr,"pthread_create: %s",strerror(r)); +} +#endif + int sys_startgui(const char *guidir) { pid_t childpid; @@ -1166,6 +1180,10 @@ int sys_startgui(const char *guidir) #endif /* MSW */ } + +#ifdef QTGUI + if (sys_qtcanvas) sys_start_qt(); +#endif #if defined(__linux__) || defined(IRIX) /* now that we've spun off the child process we can promote -- GitLab