Skip to content
  • 0 Votes
    7 Posts
    361 Views
    Christian EhrlicherC
    That's the reason we request a mre 🙂
  • 0 Votes
    5 Posts
    990 Views
    A
    @SGaist Thanks again for your reply, it really gave me the key to know what was going on. The problem was that the Connections were defined in a component that was continuously being created and destroyed, as it is part of a StackView. With this behaviour, every time the component was created, a new connection was defined. Moving the connections to a general component solves the problem. Thank you very much! :)
  • 0 Votes
    7 Posts
    2k Views
    S
    Well, Qt has both a QMenu and a QMenuItem. Only the QMenuItem is supposed to trigger actions. The QMenu itself only has QMenuItems and submenus. So, its action is already defined. Usually, the QMenuItems have QActions associated with it. For the QMenu::triggered signal the documentation states: This signal is emitted when an action in this menu is triggered. To me this reads that you have several entries inside the QMenu and one of these entries triggers an action. This is also why this signal contains the QAction as a parameter. My understanding would mean that clicking on the QMenu itself does not emit a triggered signal, but only clicking on a QMenuItem does.
  • 0 Votes
    10 Posts
    5k Views
    SGaistS
    @tilz0R in addition to @JonB, don't call self.show in an __init__ method. It's not the role of the widgets to make themselves visible. That is the role of the object or method creating them.
  • 0 Votes
    6 Posts
    627 Views
    G
    @Chris-Kawa Just wanted to come full circle on this. What I've ended up doing is I have a StationController class which is injected with a StateCommander class. The Station controller then builds the state machine internally and connects to the concrete StateCommander's signals to be used for transitions. The state commander can be a UiCommander or a CLICommander etc. The base StateCommander class has methods such as LoadProduct which the UiCommander can override if need be, but the base class will just emit a RequestProductLoad signal. When the Commander is passed to the StationController, the StationController registers for the Commanders signals. So the UiCommander could contain a reference to the Ui components it needs, but a different commander wouldn't need to know anything about the UI. In this case I have a UiCommander which forwards button clicks signals to the generic signals the StationController is connected to. The state functionality remains static and is not coupled to a UI at all, but instead is coupled to just an abstract StateCommander. I had come across this example and really didn't like it because the states were so tightly coupled to the UI. The states take a Scene as an input and I knew I didn't want my states taking in UI components. By delegating the triggers to my StateCommander class, the state machine has no knowledge of whether the system is headless or not and the states can transition along just fine. I then have a UiController which contains the main window and it registers for events from my StationController and can update the MainWindow accordingly by calling main_window->setPage(page); The main window is just dumb and displays whatever the controller tells it to. I really like the decoupling but one thing I'm not a huge fan of is that the state is driven by a single Commander object, and if the station gets more and more complex, I will have to keep cramming functionality into that single interface. But, I think that's what you eluded to in the post I'm replying to, and I can live with that for now.
  • 0 Votes
    6 Posts
    2k Views
    L
    @oblivioncth same here. Neither Macro nor register function needed. no related documents.
  • 0 Votes
    2 Posts
    620 Views
    lorn.potterL
    I am not sure Qt signals would work. You should certainly be able to so callbacks though.
  • 0 Votes
    7 Posts
    1k Views
    S
    @JonB Oh, I thought I had the same, fixed it, thanks
  • QT QImage Read From Error

    Unsolved General and Desktop qimage qthread signals & slots qfileinfo
    23
    0 Votes
    23 Posts
    4k Views
    JonBJ
    @mvsri said in QT QImage Read From Error: image_path is nothing but a QString which stores the path to a bmp image in a folder. the path is static it doesn't change. I know that! My question is about the content of that file. I don't know whether the image writing is finished or not. that's why i used QFile exists to check if the file is created or not and read the image if the path exists. But that doesn't tell you anything about whether it has started but not finished writing to that file, does it? (Unless you are relying on Windows or something not allowing a file to satisfy "exists" until it has been closed, which I would see as dodgy in the extreme.) In which case, you will read in an incomplete image file, maybe that's why you have "black" at the bottom? At least put in a qDebug() << image.sizeInBytes() after loading it (though I'm not sure if that's reliable).... QFile::remove(image_path); It gets worse! This, or renaming: how do you know that at the instant you execute this the camera has not re-started writing to that file for the next capture, and you are (trying to) removing/renaming a file while it is being written anew? Is your camera-image-capture-write-to-file a separate process from your code? How do you know when the capture has started/finished writing to the file?
  • 0 Votes
    7 Posts
    2k Views
    JonBJ
    @SpaceToon If you are determined to keep the signal class and the slot class separate without sharing a common enum, but you are prepared to do things via a common "controller" class, you can proceed as follows: Export the two enums from their .h files. Import these two files into the "controller" class. Have the controller class place the connect() from the signal class to the slot class. The call to the connect() attaches the signal with its enum to a lambda (or similar) in the controller which maps/translates the signal's enum value to the corresponding slot's enum value.
  • 0 Votes
    10 Posts
    960 Views
    S
    @SpaceToon said in Is it possible to receive a signal from a class that was instantiated twice?: int main(int argc, char *argv[]) { QApplication a(argc, argv); MainWindowA m; m.show(); return a.exec(); } Where is your MainWindowB instance create? Does MainWindowA do this somewhere? In general, I would expect something along these lines in main: int main(int argc, char *argv[]) { QApplication a(argc, argv); emitSignalClass emitter; MainWindowA mA(&emitter); mA.show(); MainWindowB mB(&emitter); mB.hide(); return a.exec(); } Create an instance of your signal-emitting class first and hand it to the constructurs. Store a pointer to the same emitter object as member variable in both MainWindowA and MainWindowB.
  • Accessing MainWindow object from another class

    Unsolved General and Desktop signals & slots widget
    15
    0 Votes
    15 Posts
    9k Views
    JonBJ
    @TUStudi I do believe this is the neater way to go. Your MainWindow and your TestClass are now quite independent of each other. If you had done "call a slot from MainWindow directly" TestClass would not be (re-)usable without MainWindow.
  • 0 Votes
    4 Posts
    631 Views
    SGaistS
    Your BluetoothController should have a member variable of the BluetoothModel class. Your BluetoothModel class should provide an API that your BluetoothController can connect to and also that provides whatever data is needed.
  • 0 Votes
    4 Posts
    1k Views
    jsulmJ
    @Rizwan94 I never used QNAM, so do not know whether better to use that one or QNetworkReply Yes
  • 0 Votes
    13 Posts
    4k Views
    Matthew11M
    OK as @J.Hilk said: @J.Hilk said in Passing custom type pointers between threads via signals and slots cause app to crash: are you by any chance exposing those thread-shared custom types directly to qml? And: @J.Hilk said in Passing custom type pointers between QML and threads via signals and slots cause app to crash: I can only tell you that I always ran into trouble when I tried to access/manipulate c++ threaded stuff (directly)via QML. Indeed that was causing the crashes. The solution is to create a copy of the resource that is sent from QML and then send a copy of that resource to thread. As @J.Hilk suggested Manager object should do the job which is: @Matthew11 said in [Passing custom type pointers between QML and threads via signals and slots cause app to crash Manager <-> Threads : communicate via signal/slots with QueuedConnection synchronization/locking on the shared resource Manager <-> QML signals and slots or directly from the manager's memory Below you can find my working example. This is very similar to the code which I provided in the first post. You send a dispatch from QML to specific Contractor, Contractor then is doing his job and return the result back to QML (sends task with input data scenario). Or you send a dispatch to Contractor to retrieve some data (send task with no input data scenario). ContractorTask is no longer exposed to QML. But pointers are no longer send however it is possible in the C++ domain (across main (Manager) and workers threads with proper locking/synchronization). If you want to feel how it is when app is crashing uncomment the line _taskCopy.setData(_data); from pushTaskToContractor() in Controller.h which disabling the step of making the copy of the resource. Thank you all for your help in solving the problem! Code: //.pro QT += quick CONFIG += c++11 SOURCES += \ Contractor.cpp \ main.cpp RESOURCES += qml.qrc HEADERS += \ Contractor.h \ ContractorTask.h \ Controller.h // Contractor.h #ifndef CONTRACTOR_H #define CONTRACTOR_H #include <QObject> #include <ContractorTask.h> class Contractor : public QObject { Q_OBJECT public: Contractor(int _ID, QObject* parent = nullptr); int getID() { return ID; } public slots: void executeTask(ContractorTask _task); signals: void finished(); void taskStarted(ContractorTask _task); void taskFinished(ContractorTask _task); private: int ID; }; #endif // CONTRACTOR_H // Contractor.cpp #include "Contractor.h" #include <QDebug> #include <QThread> Contractor::Contractor(int _ID, QObject *parent) : QObject(parent), ID(_ID) {} void Contractor::executeTask(ContractorTask _task) { emit(taskStarted(_task)); if(getID() != _task.getConctractorID()) { qDebug() << "Not mine ID, discarding"; return; } QVariant localData = _task.getData(); switch(_task.getTaskID()) { case 0: // PASS TASK TO C++ TO RETRIEVE DATA { QList<QVariant> _params; _params.append(12.5F); _params.append(14.36F); QVariant _data = _params; _task.setData(_data); qDebug() << "PASS TASK TO C++ TO RETRIEVE DATA"; } break; case 1: // PASS TASK WITH DATA TO C++ AND GET THE SAME DATA BACK IN QML { QList<QVariant> _params; _params = localData.value<QList<QVariant>>(); QList<float> _floats; int counter = 0; for(auto item : _params) { _floats << item.toFloat(); qDebug() << "Getting data in C++ from QML (QList<float>): item =" << counter++ << "value =" << item; } qDebug() << "PASS TASK WITH DATA TO C++ AND GET THE SAME DATA BACK IN QML"; } break; default: { qDebug() << "Oh... I don't have these one :("; } } emit(taskFinished(_task)); } // ContractorTask.h #ifndef CONTRACTORTASK_H #define CONTRACTORTASK_H #include <QVariant> class ContractorTask { public: ContractorTask() : taskID(-1), contractorID(-1), data("") {} int getTaskID() { return taskID; } void setTaskID(int _ID) {taskID = _ID; } int getConctractorID() { return contractorID; } void setContractorID(int _ID) { contractorID = _ID; } QVariant getData() { return data; } void setData(QVariant _data) { data = _data; } private: int taskID; int contractorID; QVariant data; }; Q_DECLARE_METATYPE(ContractorTask) #endif // CONTRACTORTASK_H // Controller.h #ifndef CONTROLLER #define CONTROLLER #include <QObject> #include <QThread> #include <QDebug> #include <Contractor.h> #include <ContractorTask.h> class Controller : public QObject { Q_OBJECT QThread workerThread; public: Controller() { Contractor *worker = new Contractor(0); worker->moveToThread(&workerThread); connect(&workerThread, &QThread::finished, worker, &QObject::deleteLater); connect(this, &Controller::startTask, worker, &Contractor::executeTask); connect(worker, &Contractor::taskStarted, this, &Controller::contractorStartedTask); connect(worker, &Contractor::taskFinished, this, &Controller::contractorFinishedTask); workerThread.start(); } ~Controller() { workerThread.quit(); workerThread.wait(); } signals: void startTask(ContractorTask); void taskStarted(int id, int contractor, QVariant data); void taskEnded(int id, int contractor, QVariant data); public slots: void pushTaskToContractor(int _id, int _contractor, QVariant _data) { // QVariant depends to QML, so make COPY of QVariant CONTENT, before passing it to thread: QList<QVariant> _params; _params = _data.value<QList<QVariant>>(); QVariant _dataToSend = _params; ContractorTask _taskCopy; _taskCopy.setTaskID(_id); _taskCopy.setContractorID(_contractor); _taskCopy.setData(_dataToSend); // Sending local data copy is OK // _taskCopy.setData(_data); // Sending _data (has source in QML) = PROGRAM CRASH!!! emit(startTask(_taskCopy)); } void contractorFinishedTask(ContractorTask _task) { // Passing COPY of ContractorTask to QML: emit(taskEnded(_task.getTaskID(), _task.getConctractorID(), _task.getData())); } void contractorStartedTask(ContractorTask _task) { // Passing COPY of ContractorTask to QML: emit(taskStarted(_task.getTaskID(), _task.getConctractorID(), _task.getData())); } }; #endif // CONTROLLER // main.cpp #include <QGuiApplication> #include <QQmlApplicationEngine> #include <Controller.h> #include <QQmlContext> int main(int argc, char *argv[]) { QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); QGuiApplication app(argc, argv); Controller TaskController; qRegisterMetaType<ContractorTask>(); QQmlApplicationEngine engine; engine.rootContext()->setContextProperty("TaskController", &TaskController); const QUrl url(QStringLiteral("qrc:/main.qml")); QObject::connect(&engine, &QQmlApplicationEngine::objectCreated, &app, [url](QObject *obj, const QUrl &objUrl) { if (!obj && url == objUrl) QCoreApplication::exit(-1); }, Qt::QueuedConnection); engine.load(url); // Get item from QML, and connect it's signal (startTaskFromQML) to Controller QObject *item = engine.rootObjects().first(); QObject::connect(item, SIGNAL(startTaskFromQML(int, int, QVariant)), &TaskController, SLOT(pushTaskToContractor(int, int, QVariant))); return app.exec(); } // main.qml import QtQuick 2.12 import QtQuick.Controls 2.5 ApplicationWindow { id: root visible: true width: 640 height: 480 title: qsTr("Test") signal startTaskFromQML(int id, int contractor, variant data) property variant _data: 0 Connections { target: TaskController onTaskEnded: console.log("Contractor with ID =", contractor, "finished task with ID = ", id, "and returned result:", data); onTaskStarted: console.log("Contractor with ID =", contractor, "started task with ID = ", id); } Column { id: column anchors.horizontalCenter: parent.horizontalCenter anchors.verticalCenter: parent.verticalCenter Button { id: passAndGet text: qsTr("PASS TASK WITH DATA TO C++ AND GET THE SAME DATA BACK IN QML") anchors.horizontalCenter: parent.horizontalCenter onClicked: { _data= [1.2, 3.4, 5.6, 7.8] for(var i = 0; i < 50; i++) { root.startTaskFromQML(1, 0, _data) } } } Button { id: getData text: qsTr("PASS TASK TO C++ TO RETRIEVE DATA") anchors.horizontalCenter: parent.horizontalCenter onClicked: { _data = 0 root.startTaskFromQML(0, 0, _data) } } } } // qtquickcontrols2.conf [Controls] Style=Material // qml.qrc <RCC> <qresource prefix="/"> <file>main.qml</file> <file>qtquickcontrols2.conf</file> </qresource> </RCC>
  • 0 Votes
    19 Posts
    4k Views
    jsulmJ
    @smnsmn said in Connecting several readyRead() signals to one slot (QSerialPort): Qt::QueuedConnection The slot is invoked when control returns to the event loop of the receiver's thread. The slot is executed in the receiver's thread. This is for queued connections which are not used by default for signals/slots in same thread. You really need to differentiate between connections in same thread and such between different threads. "Can signal thread == receiver thread?" - sure, it is like this most of the time. Only if you use more than one thread you can have signals and slots in different threads. For signals and slots in same thread queued connection is NOT used, unless you tell Qt to do so (last parameter in connect() call).
  • 0 Votes
    7 Posts
    2k Views
    O
    @SGaist I tried ffmpeg and vlc sadly with those libraries there were 2 seconds of delay. I want stream to be realtime. Plus my friend needs to access each frame in order to process it. With QT we can do such thing thanks to QByteArray and QBuffer.
  • 0 Votes
    7 Posts
    1k Views
    Pl45m4P
    @mrjj If it works with setters, it should be fine. I'm relatively new to Qt and since you have signals and slots, I thought using setters is maybe not the best way, so there MUST be another solution :) haha Ok I will try it out tomorrow and let you know if it worked for me :) EDIT: @mrjj @SGaist Thank you guys, passing the pointer to my data with constructor and setting the data to a local member to use it inside my WindowChildClass worked for me.
  • 0 Votes
    17 Posts
    4k Views
    Y
    @SGaist I am not using Labview's serial port directly because of my code contain many background functionalities. It will take time to implement all in Labview. We want to just give readable data and few User interface to Labview. So user can directly use readable value and interface in Labview.
  • Duplication of object in C++ and QML

    Solved General and Desktop qml signals & slots
    7
    0 Votes
    7 Posts
    2k Views
    T
    AHA! In QML, wrap the QObject-derived classes that you made in an Item{} and findChild will find them just fine.