I
I
Ian Smirnovski2020-02-04 09:53:55
Qt
Ian Smirnovski, 2020-02-04 09:53:55

Qt - how to pass a signal?

There is a question about signaling in Qt (mb it's even a question of application design...)
Let's say I have a class MainWindow : QMainWindow. I placed on a form QStackedWidget (или QTabWidget)with two pages (tabs). Moreover, the widgets on the tabs are separate classes: ViewEditor: QWidgetand TextEditor:QWidget(each has its own elements inside) . On the tab ViewEditoris QGraphicsViewc QGraphicsScene.Scene displays QGraphicsItem(squares) . I want that when clicking on a square, its ID is displayed in QTextEditthe tab TextEditor:QWidget. Question: when you click on the square, emit SOME_SIGNAL. This emit is captured by the scene and passed to all widgets up the chain until it reachesQTextEdit. Is there a more elegant mechanism to pass a signal from object to object if there are more objects in between? It turns out a very confusing sequence of signals and slots ...

Answer the question

In order to leave comments, you need to log in

2 answer(s)
V
Vitaly, 2020-02-04
@vt4a2h

This emit is picked up by the scene and passed to all the widgets up the chain until it reaches the QTextEdit.

This is not entirely true. Signal and event are different things in Qt. The signal is "picked up" by the receivers to which it is connected. There may be zero or more such receivers. The receiver is usually a slot of another object or a lambda function.
That is, if you want to pass something directly to QTextEdit and there is a slot you need, you can connect the slot and the signal directly. If not, then you can create a slot (or just any method) in some class that inherits from QObject and perform the necessary transformations there. Or use a lambda function.

I
Ian Smirnovski, 2020-02-04
@smirnovskoe

void MainWindow::MainWindow()
{
    stackedWidget = new QStackedWidget();

    viewWidget = new ViewWidget(); // унаследован от QWidget
    textWidget = new TextWidget();   // унаследован от QWidget
    // ----------------------------
    stackedWidget->addWidget(viewWidget );
    stackedWidget->addWidget(textWidget );
}

TextWidgetcontains QTabWidget. Each time you click on the box, !!should!! a new tab is created, (which is also a separate class TextArea: QWidgetthat contains QTextEditc information (id) QGraphicsItem-а)
TextWidget::TextWidget(MainWindow *parent) : p_parent(parent)
{
    tabWidget = new QTabWidget();

    tabWidget->setTabsClosable(true);

    QHBoxLayout *mainLay = new QHBoxLayout(this);
    mainLay->addWidget(tabWidget);
    setLayout(mainLay);
}

ViewWidget::ViewWidget(MainWindow *parent) : p_parent(parent)
{
        scene = new GraphicsScene();
        graphicsView = new GraphicsView(scene);
}

Creating a graphic element:
void GraphicsScene::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
    if (event->button() == Qt::LeftButton && m_addNode)
    {
        if(!itemAt(event->scenePos(),QTransform())){
            Node *newNode = new Node();
            addItem(newNode);
        }
    }

QGraphicsItemI have a Node class. And now, in the mousePressEvent method of the Node class, emit SOME_SIGNAL should be done. The issue is that Node:QGraphicsItem knows nothing about the existence of the TextWidget with its TextArea tabs. Objects and their signals and slots are connected! But TextWidget and TextArea are created "at the top level" and Node:QGraphicsItem is further down. Here I am a little confused and do not fully understand how to implement this mechanism ((

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question