|
Post by bigbass on Jun 1, 2022 16:52:42 GMT 1
Qt5 is not an easy thing to use. but it is very powerful and many professional apps have been made with it en.wikipedia.org/wiki/Qt_(software)That being said mixing it with bacon can be a mind bending experience since Qt uses their own way of connecting events with SIGNALS and SLOTS (they don't use the standard callbacks) and it uses C++ that was my warning label and legal disclaimer you could stop here there was a first demo of Qt4 as a window with no events posted to bacon basic-converter.proboards.com/post/10101/threadQt5 has changed a lot and getting the signals / slots idea to work in bacon took me quite a bit of time to get it working this demo uses the raspberry pi 3 you would need to edit -I/usr/include/arm-linux-gnueabihf/qt5 to the location of your qt5 headers most code will port from qt4 to qt5 with this
PRAGMA INCLUDE <QtWidgets/QApplication> <QtWidgets/QLabel> <QtWidgets/QMainWindow> <QtWidgets/QPushButton> PRAGMA LDFLAGS -lQt5Widgets -lQt5Gui -lQt5Core -lGLESv2 -lpthread -latomic PRAGMA COMPILER g++ PRAGMA OPTIONS -Wno-write-strings -Wno-pointer-arith -I/usr/include/arm-linux-gnueabihf/qt5
OPTION PARSE FALSE
PRAGMA INCLUDE <QtWidgets/QApplication> <QtWidgets/QLabel> <QtWidgets/QMainWindow> <QtWidgets/QPushButton> PRAGMA LDFLAGS -lQt5Widgets -lQt5Gui -lQt5Core -lGLESv2 -lpthread -latomic PRAGMA COMPILER g++ PRAGMA OPTIONS -Wno-write-strings -Wno-pointer-arith -I/usr/include/arm-linux-gnueabihf/qt5
OPTION PARSE FALSE
'--- our signal /slot from Qt placed in a bacon SUB SUB handleButton() PRINT "Qt callback hack working with events" '--- change the text m_button->setText("Example") '--- resize button m_button->resize(100,100) ENDSUB
DECLARE app TYPE QApplication* DECLARE mainWindow TYPE QMainWindow* DECLARE m_button TYPE QPushButton* app = new QApplication(argc, argv)
'--- mainwindow.cpp used in Qt modified and redirected the signal/slot to a bacon SUB '--- Create the button m_button = new QPushButton("Qt Button") '--- set size and location of the button m_button->setGeometry(QRect(QPoint(100, 100), QSize(200, 50))) '--- Connect button signal to appropriate slot hacked for a BaCon SUB '--- had to add the QObject:: to the connect to get this to work in bacon QObject::connect(m_button, &QPushButton::released, handleButton)
m_button->show() return app->exec()
|
|
|
Post by Pjot on Jun 1, 2022 19:00:29 GMT 1
Thanks Bigbass! Against all odds, I tried your code on my Linux Mint system, but unfortunately it didn't work there. But I'll try to revive my Raspberry VM shortly... Best regards, Peter
|
|
|
Post by bigbass on Jun 1, 2022 22:31:33 GMT 1
Hello Peter
thanks for the test and feedback
I would suspect on mint it should work by changing
RPI 3 -I/usr/include/arm-linux-gnueabihf/qt5
mint 64 amd -I/usr/include/x86_64-linux-gnu/qt5
and remove or replace the GL line -lGLESv2 with what mint uses
should work for mint 64 amd ( I don't have my mint laptop anymore)
joe
PRAGMA INCLUDE <QtWidgets/QApplication> <QtWidgets/QLabel> <QtWidgets/QMainWindow> <QtWidgets/QPushButton> PRAGMA LDFLAGS -lQt5Widgets -lQt5Gui -lQt5Core -lpthread -latomic PRAGMA COMPILER g++ PRAGMA OPTIONS -Wno-write-strings -Wno-pointer-arith -I/usr/include/x86_64-linux-gnu/qt5 OPTION PARSE FALSE
|
|
|
Post by bigbass on Jun 2, 2022 16:25:34 GMT 1
this is the demo in pure qt (scroll down the page for the source code to build the widget) wiki.qt.io/How_to_Use_QPushButtonHello I will include the source files that I used to port the demo to bacon 1.) this way anyone can test the code and their qt is working correctly 2.) it will provide a reference to what to do to port the code to bacon once confirmed on other systems Will add a step by step detailed list of what to look for while porting to get all the headers and callbacks working and if any changes need to be made to the class to get it all public tips : once you get the official makefile generated from the source code it makes adding the correct PRAGMA lines easier to port the code joe
|
|
|
Post by bigbass on Jun 3, 2022 16:10:59 GMT 1
Good news QT5 can work in the same way as the fltk coding style except for the connect line here is another widget a checkbox with the low level events from qt hope this demo works for everyone I think that QT5 has the door open now with bacon and events this is starting to be fun again
PRAGMA INCLUDE <QtWidgets/QApplication> <QtWidgets/QMainWindow> <QtWidgets/QCheckBox> <QtWidgets/QHBoxLayout> PRAGMA LDFLAGS -lQt5Widgets -lQt5Gui -lQt5Core -lGLESv2 -lpthread -latomic PRAGMA COMPILER g++ PRAGMA OPTIONS -Wno-write-strings -Wno-pointer-arith -I/usr/include/arm-linux-gnueabihf/qt5
OPTION PARSE FALSE
'--- our signal /slot from Qt placed in a bacon SUB '------------------------------------------------------ SUB showTitle() '------------------------------------------------------ PRINT "Qt callback hack working with events" IF (cb->isChecked()) THEN w->setWindowTitle("Checked") ELSE w->setWindowTitle("Unchecked") ENDIF ENDSUB
DECLARE app TYPE QApplication* DECLARE window TYPE QMainWindow* DECLARE hbox TYPE QHBoxLayout* DECLARE cb TYPE QCheckBox* DECLARE w TYPE QWidget* app = new QApplication(argc, argv) '--- Create a widget instead of a window w = new QWidget() hbox = new QHBoxLayout() cb = new QCheckBox("Show Title") hbox->addWidget(cb, 0, Qt::AlignLeft | Qt::AlignTop) '--- Set the hbox as the layout of the widget '--- this fixes having a window and a widget that are not joined w->setLayout(hbox )
QObject::connect(cb, &QCheckBox::stateChanged, showTitle)
cb->show() w->resize(350, 150) w->setWindowTitle("QCheckBox demo") w->show() return app->exec()
|
|
|
Post by bigbass on Jun 3, 2022 17:08:59 GMT 1
one more for fun just to see if the idea will work for more widgets the callback is all qt updating the label PRAGMA INCLUDE <QtWidgets/QApplication> <QtWidgets/QMainWindow> <QtWidgets/QCheckBox> <QtWidgets/QHBoxLayout> <QtWidgets/QLabel> <QtWidgets/QSlider> PRAGMA LDFLAGS -lQt5Widgets -lQt5Gui -lQt5Core -lGLESv2 -lpthread -latomic PRAGMA COMPILER g++ PRAGMA OPTIONS -Wno-write-strings -Wno-pointer-arith -I/usr/include/arm-linux-gnueabihf/qt5
OPTION PARSE FALSE
DECLARE app TYPE QApplication* DECLARE window TYPE QMainWindow* DECLARE hbox TYPE QHBoxLayout* DECLARE cb TYPE QCheckBox* DECLARE w TYPE QWidget* DECLARE slider TYPE QSlider* DECLARE label TYPE QLabel* app = new QApplication(argc, argv) '--- Create a widget instead of a window w = new QWidget() hbox = new QHBoxLayout() slider = new QSlider(Qt::Horizontal ) hbox->addWidget(slider)
hbox->addWidget(slider, 0, Qt::AlignLeft | Qt::AlignTop) label = new QLabel("0") hbox->addWidget(label) '--- Set the hbox as the layout of the widget '--- this fixes having a window and a widget that are not joined w->setLayout(hbox ) '---no callback in SUB since the label handels the changes of the slider QObject::connect(slider, &QSlider::valueChanged, label,qOverload<int>(&QLabel::setNum))
w->resize(350, 150) w->setWindowTitle("Qt5 slider demo") w->show() return app->exec()
|
|
|
Post by Pjot on Jun 3, 2022 17:14:21 GMT 1
Thanks bigbass, The below code works for me in Linux Mint 20.3. BR Peter
PRAGMA INCLUDE <QtWidgets/QApplication> <QtWidgets/QLabel> <QtWidgets/QMainWindow> <QtWidgets/QPushButton> PRAGMA LDFLAGS -lQt5Widgets -lQt5Gui -lQt5Core -lpthread -latomic PRAGMA COMPILER g++ PRAGMA OPTIONS -Wno-write-strings -Wno-pointer-arith -I/usr/include/x86_64-linux-gnu/qt5 -fPIC OPTION PARSE FALSE
'--- our signal /slot from Qt placed in a bacon SUB SUB handleButton() PRINT "Qt callback hack working with events" '--- change the text m_button->setText("Example") '--- resize button m_button->resize(100,100) ENDSUB
DECLARE app TYPE QApplication* DECLARE mainWindow TYPE QMainWindow* DECLARE m_button TYPE QPushButton* app = new QApplication(argc, argv)
'--- mainwindow.cpp used in Qt modified and redirected the signal/slot to a bacon SUB '--- Create the button m_button = new QPushButton("Qt Button") '--- set size and location of the button m_button->setGeometry(QRect(QPoint(100, 100), QSize(200, 50)))
'--- Connect button signal to appropriate slot hacked for a BaCon SUB '--- had to add the QObject:: to the connect to get this to work in bacon QObject::connect(m_button, &QPushButton::released, handleButton)
m_button->show() return app->exec()
|
|
|
Post by bigbass on Jun 3, 2022 18:14:25 GMT 1
Hello Peter
great to hear you got it to compile on mint with your fix
-I/usr/include/x86_64-linux-gnu/qt5 -fPIC
so it seems that with this x86 template it should work with the other demos by adding the correct <QtWidgets/ that were used here >
PRAGMA INCLUDE <QtWidgets/QApplication> <QtWidgets/QLabel> <QtWidgets/QMainWindow> <QtWidgets/QPushButton> PRAGMA LDFLAGS -lQt5Widgets -lQt5Gui -lQt5Core -lpthread -latomic PRAGMA COMPILER g++ PRAGMA OPTIONS -Wno-write-strings -Wno-pointer-arith -I/usr/include/x86_64-linux-gnu/qt5 -fPIC OPTION PARSE FALSE
joe
|
|
|
Post by vovchik on Jun 3, 2022 18:40:23 GMT 1
Dear Joe and Peter,
Works great for me on Mint, using Peter's example. I will now try on my Pi4 and report back.
Thanks!
With kind regards, vovchik
|
|
|
Post by bigbass on Jun 3, 2022 19:59:01 GMT 1
Hello vovchik !
First great to hear from you and that it works on your box too
the -fPIC works on the rpi3 and without it but it is safer to use it since we are mixing callbacks
here is the slider with a bacon callback
PRAGMA INCLUDE <QtWidgets/QApplication> <QtWidgets/QMainWindow> <QtWidgets/QCheckBox> <QtWidgets/QHBoxLayout> <QtWidgets/QLabel> <QtWidgets/QSlider> PRAGMA LDFLAGS -lQt5Widgets -lQt5Gui -lQt5Core -lGLESv2 -lpthread -latomic PRAGMA COMPILER g++ PRAGMA OPTIONS -Wno-write-strings -Wno-pointer-arith -I/usr/include/arm-linux-gnueabihf/qt5 -fPIC OPTION PARSE FALSE
'--- our signal /slot from Qt placed in a bacon SUB SUB handleslider() '--- print out to the terminal the sliders value '--- this shows that we can use qt5 code in the bacon callback too PRINT slider->value() ENDSUB
DECLARE app TYPE QApplication* DECLARE window TYPE QMainWindow* DECLARE hbox TYPE QHBoxLayout* DECLARE cb TYPE QCheckBox* DECLARE w TYPE QWidget* DECLARE slider TYPE QSlider* DECLARE label TYPE QLabel* app = new QApplication(argc, argv) '--- Create a widget instead of a window w = new QWidget() hbox = new QHBoxLayout() slider = new QSlider(Qt::Horizontal ) hbox->addWidget(slider)
hbox->addWidget(slider, 0, Qt::AlignLeft | Qt::AlignTop) label = new QLabel("0") hbox->addWidget(label) '--- Set the hbox as the layout of the widget '--- this fixes having a window and a widget that are not joined w->setLayout(hbox ) '---no callback in SUB here since the label handels the changes of the slider QObject::connect(slider, &QSlider::valueChanged, label,qOverload<int>(&QLabel::setNum)) '--- pass to the bacon SUB then use the sliders value QObject::connect(slider, &QSlider::valueChanged, handleslider)
w->resize(350, 150) w->setWindowTitle("Qt5 slider demo") w->show() return app->exec()
|
|
|
Post by vovchik on Jun 3, 2022 20:31:18 GMT 1
Dear Joe, Thanks, and good to see you here too, again, and pushing the envelope. I just tried the qt examples on my Pi4 and everything works perfectly. I also like the binary size I get: < 20k stripped. I think we might want to start thinking about some kind of simplified GUI syntax, like HUG, soon. With kind regards, vovchik
|
|
|
Post by bigbass on Jun 3, 2022 20:36:19 GMT 1
one more for today I am always looking for something easier and less things to remember and type on the bacon side of things we can do much to help with the C++ code and make it easier to digest combobox widget
PRAGMA INCLUDE <QtWidgets/QApplication> <QtWidgets/QMainWindow> <QtWidgets/QComboBox> <QtWidgets/QHBoxLayout> <QtWidgets/QLabel> PRAGMA LDFLAGS -lQt5Widgets -lQt5Gui -lQt5Core -lGLESv2 -lpthread -latomic PRAGMA COMPILER g++ PRAGMA OPTIONS -Wno-write-strings -Wno-pointer-arith -I/usr/include/arm-linux-gnueabihf/qt5
OPTION PARSE FALSE
DECLARE app TYPE QApplication* DECLARE window TYPE QMainWindow* DECLARE hbox TYPE QHBoxLayout* DECLARE combo TYPE QComboBox* DECLARE label TYPE QLabel* DECLARE w TYPE QWidget* 'DECLARE combotext TYPE QString app = new QApplication(argc, argv)
DECLARE distros = { "Arch", "Xubuntu", "Redhat", "Debian","Mandriva" } TYPE QStringList '--- Create a widget instead of a window w = new QWidget() hbox = new QHBoxLayout() combo = new QComboBox() combo->addItems(distros) hbox->addWidget(combo) hbox->addSpacing(15) label = new QLabel("Arch") hbox->addWidget(label) '--- Set the hbox as the layout of the widget '--- this fixes having a window and a widget that are not joined w->setLayout(hbox )
QObject::connect(combo, qOverload<const QString &>(&QComboBox::activated),label, &QLabel::setText) w->resize(350, 150) w->setWindowTitle("Qcombox demo") w->show() return app->exec()
|
|
|
Post by bigbass on Jun 4, 2022 1:24:35 GMT 1
how about a statusbar widget demo looks like we will be able to add many widgets and notice never using the C++ class in the code had to modify this a lot for bacon use with any alignment the statusbar wouldn't show PRAGMA INCLUDE <QtWidgets/QApplication> <QtWidgets/QMainWindow> <QtWidgets/QComboBox> <QtWidgets/QHBoxLayout> <QtWidgets/QLabel> PRAGMA INCLUDE <QtWidgets/QLabel> <QtWidgets/QPushButton> <QtWidgets/QStatusBar> <QtWidgets/QFrame> PRAGMA LDFLAGS -lQt5Widgets -lQt5Gui -lQt5Core -lGLESv2 -lpthread -latomic PRAGMA COMPILER g++ PRAGMA OPTIONS -Wno-write-strings -Wno-pointer-arith -I/usr/include/arm-linux-gnueabihf/qt5 -fPIC
OPTION PARSE FALSE
'-------------------------------------- SUB OnOkPressed() '-------------------------------------- Statusbar->showMessage( "OK button pressed", 4000) '---note the 4000 is 4 seconds to view the message PRINT "OK button pressed" END SUB
'-------------------------------------- SUB OnApplyPressed() '-------------------------------------- Statusbar->showMessage("Apply button pressed", 4000) PRINT "Apply button pressed" END SUB
DECLARE app TYPE QApplication* DECLARE frame TYPE QFrame* DECLARE hbox TYPE QHBoxLayout* DECLARE okBtn TYPE QPushButton* DECLARE aplBtn TYPE QPushButton* DECLARE label TYPE QLabel* DECLARE Statusbar TYPE QStatusBar* DECLARE w TYPE QWidget*
app = new QApplication(argc, argv) '--- Create a widget instead of a window w = new QWidget() frame = new QFrame() 'setCentralWidget(frame)
hbox = new QHBoxLayout(frame)
okBtn = new QPushButton("OK", frame) hbox->addWidget(okBtn, 0, Qt::AlignLeft | Qt::AlignTop)
aplBtn = new QPushButton("Apply", frame) hbox->addWidget(aplBtn, 1, Qt::AlignLeft | Qt::AlignTop) Statusbar = new QStatusBar() '--- Set the hbox as the layout of the widget '--- this fixes having a window and a widget that are not joined hbox->addWidget(Statusbar, 2) w->setLayout(hbox )
QObject::connect(okBtn, &QPushButton::clicked, OnOkPressed) QObject::connect(aplBtn, &QPushButton::clicked, OnApplyPressed) Statusbar->show() w->resize(450, 150) w->setWindowTitle("Statusbar demo") w->show() return app->exec()
|
|
|
Post by bigbass on Jun 5, 2022 1:23:23 GMT 1
I added a few things to get the output and a new Qt macro DEF FN PRINTOUT(x) = qDebug() << (x) Qt forces you to use debug for terminal out stuff
PRAGMA INCLUDE <QtWidgets/QApplication> <QtWidgets/QMainWindow> <QtWidgets/QComboBox> <QtWidgets/QHBoxLayout> <QtWidgets/QLabel> PRAGMA INCLUDE <QtWidgets/QPushButton> <QtWidgets/QStatusBar> <QtWidgets/QFrame> <QtWidgets/QVBoxLayout> PRAGMA INCLUDE <QtWidgets/QListWidget> <QtCore/QDebug> PRAGMA INCLUDE <iostream> PRAGMA LDFLAGS -lQt5Widgets -lQt5Gui -lQt5Core -lGLESv2 -lpthread -latomic PRAGMA COMPILER g++ PRAGMA OPTIONS -Wno-write-strings -Wno-pointer-arith -I/usr/include/arm-linux-gnueabihf/qt5 -fPIC OPTION PARSE FALSE
'---must include this <QtCore/QDebug> '--- a new macro without formatting or casting or c++ DEF FN PRINTOUT(x) = qDebug() << (x)
'-------------------------------------- SUB addPressed() '-------------------------------------- Statusbar->showMessage( "add", 4000) '---note the 4000 is 4 seconds to view the message END SUB
'-------------------------------------- SUB renamePressed() '-------------------------------------- Statusbar->showMessage("rename ", 4000) END SUB '-------------------------------------- SUB removePressed() '-------------------------------------- Statusbar->showMessage("remove", 4000) END SUB '-------------------------------------- SUB removeallPressed() '-------------------------------------- Statusbar->showMessage("remove all ", 4000) END SUB
'-------------------------------------- SUB clickedsub() '-------------------------------------- '--- I figured out how to get the selected from a click Statusbar->showMessage(lw->currentItem()->text(), 4000) '--- how to get the terminal out strings of the selected text PRINTOUT(lw->currentItem()->text()) END SUB
DECLARE app TYPE QApplication* DECLARE hbox TYPE QHBoxLayout* DECLARE vbox TYPE QVBoxLayout* DECLARE add TYPE QPushButton* DECLARE renamed TYPE QPushButton* DECLARE removeme TYPE QPushButton* DECLARE removeall TYPE QPushButton* DECLARE lw TYPE QListWidget* DECLARE Statusbar TYPE QStatusBar* DECLARE w TYPE QWidget*
app = new QApplication(argc, argv) '--- Create a widget instead of a window w = new QWidget() hbox = new QHBoxLayout() vbox = new QVBoxLayout() lw = new QListWidget() lw->addItem("apples") lw->addItem("oranges") lw->addItem("mangos") lw->addItem("bananas") lw->addItem("lemons")
add = new QPushButton("Add") renamed = new QPushButton("Rename") removeme = new QPushButton("Remove") removeall = new QPushButton("Remove All")
vbox->setSpacing(3) vbox->addStretch(1) vbox->addWidget(add) vbox->addWidget(renamed) vbox->addWidget(removeme) vbox->addWidget(removeall) vbox->addStretch(1) hbox->addWidget(lw) hbox->addSpacing(15) hbox->addLayout(vbox)
'--- Set the hbox as the layout of the widget '--- this fixes having a window and a widget that are not joined Statusbar = new QStatusBar() '---add the statusbar widget hbox->addWidget(Statusbar, 3, Qt::AlignBottom) w->setLayout(hbox )
QObject::connect(add, &QPushButton::clicked, addPressed) QObject::connect(renamed, &QPushButton::clicked, renamePressed) QObject::connect(removeme, &QPushButton::clicked, removePressed) QObject::connect(removeall, &QPushButton::clicked, removeallPressed) '--- added a custom callback to get the listwidget 'QObject::connect(lw, &QListWidget::itemDoubleClicked, doubleclickedsub) QObject::connect(lw, &QListWidget::itemClicked, clickedsub) w->resize(500, 200) w->setWindowTitle("Listwidget demo") w->show() return app->exec()
|
|
|
Post by Pjot on Jun 5, 2022 7:47:59 GMT 1
Thanks bigbass! It's pretty cool how these widgets work and look like. Your code demonstrates how quickly it can be done Best regards Peter
|
|