[SOLVED] QLayout does not work -> experimental Graph like widget



  • Currently I try to add buttons (here nodes) to an widget. My code looks like this:

    GraphWidget::GraphWidget(QWidget *parent)
    				: QWidget(parent)
    	{
    		/* Load style */
    		QFile stylefile(":/styles/src/nitro/node_graph/style.qss");
    		stylefile.open(QFile::ReadOnly);
    		QString stylestring = QLatin1String(stylefile.readAll());
    		setStyleSheet(stylestring);
    		/* Set context menu */
    		setContextMenuPolicy(Qt::CustomContextMenu);
    		connect(this, SIGNAL(customContextMenuRequested(QPoint)), SLOT(customMenuRequested(QPoint)));
    		/* Set layout */
    		layout = new QLayout(this);
    		setLayout(layout);
    	}
    

    and for adding the "node":

    void GraphWidget::addEmptyEntry(QString *NITRO_OBJECT_NAME)
    	{
    		Node *n = new Node();
    		n->setText(*NITRO_OBJECT_NAME);
    		n->move(click_pos);
    		layout->addWidget(n);
    	}
    

    But what I get is an error I do not really understand (because Qt documentation means I need to insert my widget there):

    ../src/nitro/node_graph/graph_widget.cpp:46:28: error: invalid new-expression of abstract class type 'QLayout'
       layout = new QLayout(this);
                                ^
    

    How can I fix this (and I don't want to use an NodeGraph library, I want to build it as my own)?

    ~jan


  • Moderators

    As the error says QLayout is an abstract base class. You can't instantiate it.
    Use one of the derived sub-classes like QHBoxLayout, QGridLayout etc.



  • @Chris-Kawa

    Thanks for this. I understand now what the problem is, but is there an other widget where I can get something like this (adding Buttons to an widget, position is random so no HBox or centralWidget)?


  • Moderators

    If you want to position children within a widget manually then don't use layouts at all. Also move() does nothing when widget is managed by a layout.
    So just add a child and set its geometry manually:

    ...
       /* DON'T set layout */
       //layout = new QLayout(this);
       //setLayout(layout);
    }
    
    void GraphWidget::addEmptyEntry(const QString& WHATS_WITH_THE_CAPS) { //don't pass QString as pointer
       Node* n = new Node(this); //important to pass "this" as parent
       n->setText(WHATS_WITH_THE_CAPS);
       n->move(click_pos); // is click_pos some sort of global? better make that function argument
       n->show(); // widgets not managed by layout are not shown by default so this is required
    }
    


  • @Chris-Kawa click_pos is global because an other void will set the point of it (when User makes right click the position will saved). But does show()really works here? I tried it sometimes but it shows the button in a new window.


  • Moderators

    show() will make a widget a new top level window when it has no parent or has a dialog flag set. That's why I marked setting parent ("this") as important.
    As for the click_pos- still. It would make the function reusable and more maintainable if you passed the position as an argument, and not rely on a piece of outside state. For example if later you would like to add entries "from code" and not by user interaction you could pass a position to the function. Right now you would have to "simulate click" by writing to click_pos before you call addEmptyEntry, which can have other side effects if you use it somewhere else. Bad practice.



  • @Chris-Kawa
    Sorry that was my problem didn't have seen the comment^^ Thank you :)


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.