Results 1 to 9 of 9

Thread: Dispatch menu action

  1. #1
    Join Date
    Mar 2013
    Posts
    34
    Thanks
    1

    Default Dispatch menu action

    I have three text edits: "a", "b", "c". When I type something into any of them, I can hit keyboard shortcut for undo/redo and it works as expected.

    I would like to create a menu item which when triggered would undo/redo in the currently focused text edit. Please, can someone tell me how to approach this? Do I have to create a slot (myUndo, myRedo), connect each of "a", "b", "c" to it, check manually which edit has focus and trigger undo/redo on that edit? Or are there any other, more streamlined, ways of doing this? Like connecting to parent widget and letting somehow Qt do the work?

    Related problem, although this is to be expected, is that when I connect menu action "Undo" (along with its keyboard shortcut) for edit "a" and I'm editing in "b" and I hit shortcut for "Undo", "a" gets undo-ed, instead of currently focused "b". How to make it undo "a" when "a" is selected, "b" when "b", "c" when "c"? Do I have to "rebind" the menu shortcut/action all the time?

  2. #2
    Join Date
    Apr 2012
    Posts
    13
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Re: Dispatch menu action

    Is that a good user interface design? Most users will expect it to work a more conventional way: it doesn't matter where (a, b, c) the changes are, Undo undoes the changes in the time order they were done. Unless a,b,c are separate "documents."

    Don't you need an undo stack for each? And as you say, the menu item must dispatch: invoke the undo of the focused item.

    I suppose you could put all the commands on one stack, and when dispatching, filter the stack for the topmost command that is for the focused item.

    I think the title of your thread should be more descriptive, is the thread about undo or a more general question about context-sensitive menus? I don't think that context-sensitivity (or focus sensitivity) is built into Qt menu classes.

  3. #3
    Join Date
    Mar 2013
    Posts
    34
    Thanks
    1

    Default Re: Dispatch menu action

    Consider a phone book application: there is one QLineEdit for name, other one for surname, etc. All of the QLineEdits have their own undo stacks and when focused work woth keyboard shortcuts as expected. The problem is, that I would like to be able to trigger undo/redo from menu as well...

    But maybe I misread you reply..? Thanks in any case!

  4. #4
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,319
    Thanks
    316
    Thanked 870 Times in 857 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: Dispatch menu action

    It sounds like you have set up your actions incorrectly, so instead of it behaving the way you want it to, it's behaving the way you've told it to.

    You might find QSignalMapper useful for this problem.

  5. #5
    Join Date
    Mar 2013
    Posts
    34
    Thanks
    1

    Default Re: Dispatch menu action

    It sounds like you have set up your actions incorrectly, so instead of it behaving the way you want it to, it's behaving the way you've told it to.
    Could you please tell what I am doing wrong with this setup:

    mainwindow.h:

    Qt Code:
    1. class MainWindow : public QMainWindow
    2. {
    3. Q_OBJECT
    4.  
    5. public:
    6. MainWindow(QWidget *parent = 0);
    7. ~MainWindow();
    8. QLineEdit *title;
    9. QLineEdit *name;
    10. QLineEdit *surname;
    11. };
    To copy to clipboard, switch view to plain text mode 

    mainwindow.cpp:

    Qt Code:
    1. MainWindow::MainWindow(QWidget *parent)
    2. : QMainWindow(parent)
    3. {
    4. QVBoxLayout *vbox = new QVBoxLayout();
    5. title = new QLineEdit();
    6. vbox->addWidget(title);
    7. name = new QLineEdit();
    8. vbox->addWidget(name);
    9. surname = new QLineEdit();
    10. vbox->addWidget(surname);
    11. QWidget *w = new QWidget(this);
    12. w->setLayout(vbox);
    13. this->setCentralWidget(w);
    14.  
    15. QMenu *undoMenu = menuBar()->addMenu("Edit");
    16. // undoMenu->addAction("Undo", this, SLOT(undo()), QKeySequence::Undo); // does nothing
    17. undoMenu->addAction("Undo", title, SLOT(undo()), QKeySequence::Undo); // undoes only title
    18. }
    To copy to clipboard, switch view to plain text mode 

    And thanks for the QSignalMapper link, I will have a look at it...

  6. #6
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,368
    Thanks
    3
    Thanked 5,018 Times in 4,794 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Dispatch menu action

    Quote Originally Posted by ecir.hana View Post
    Do I have to create a slot (myUndo, myRedo), connect each of "a", "b", "c" to it, check manually which edit has focus and trigger undo/redo on that edit?
    No. Track the widget that has focus using signals made available by QApplication and when your undo/redo is invoked, redirect it to that widget's undo/redo.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  7. The following user says thank you to wysota for this useful post:

    ecir.hana (17th March 2013)

  8. #7
    Join Date
    Mar 2013
    Posts
    34
    Thanks
    1

    Default Re: Dispatch menu action

    This looks like exactly what I'm after, thanks!

    I have one more question, though. Imagine that in addiction to those QLineEdits there are QPlainTextEdits as well. The parameters of "focusChanged()" are two QWidgets - how to call "undo()" on a QWidget? This is perhaps more general question C++ question but maybe Qt provides some ways about calling dynamically resolved methods. I'm asking because, for instance, Objetive C has this "respondsToSelector:" method which when returns YES, one can safely "call" a method of an object.

    Or do I have to first "qobject_cast" a QWidget to QPlainTextEdit, and if unsuccessful then cast it to QLineEdit, ..?

  9. #8
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,368
    Thanks
    3
    Thanked 5,018 Times in 4,794 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Dispatch menu action

    Use qobject_cast or dynamic_cast.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  10. #9
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,416
    Thanks
    37
    Thanked 1,544 Times in 1,494 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: Dispatch menu action

    Since undo/redo methods are also slots, you also have the option of invoking them via QMetaObject::invokeMethod()

    Qt Code:
    1. QMetaObject::invokeMethod( widgetPointer, "undo", Qt::DirectConnection );
    To copy to clipboard, switch view to plain text mode 

    Cheers,
    _

Similar Threads

  1. Can't check the action when it has a menu?
    By koilin in forum Qt Programming
    Replies: 1
    Last Post: 13th July 2012, 03:53
  2. Replies: 1
    Last Post: 4th November 2011, 11:25
  3. Action-Menu-Button
    By hgedek in forum Newbie
    Replies: 1
    Last Post: 1st October 2007, 16:41
  4. ToolBar Action With Menu
    By indifference in forum Qt Programming
    Replies: 4
    Last Post: 10th September 2007, 19:37
  5. Action on menu to display ui
    By jochen_r in forum Newbie
    Replies: 10
    Last Post: 10th January 2006, 10:10

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Qt is a trademark of The Qt Company.