Sending an Update Event to the GUI

• Mar 26, 2010 - 02:01

I'm working on a plugin that creates a new score and adds notes in real time, from info over a network socket.

A) Is there a method I can call to resync the GUI with a score object?
B) Is there a way to bring a particular score tab to the front?

The socket, I figured out. My problem is that the added notes only appear when I switch to another score's tab and back again.

This presumably notifies the GUI to re-check the score data. It's not a simple repaint since neither dragging a window over the region nor minimizing the window reveal the new notes.

My plugin isn't blocking, and the MuseScore GUI is otherwise responsive. I'm using a loop with processEvents() in it, and a non-modal dialog to break out and stop listening.
QCoreApplication.processEvents(QEventLoop.AllEvents, 500);

I wasn't able to find any tricks in the Qt library to get an instance of the main window and somehow trigger an update...

My eventual goal is similar to this feature request:
http://musescore.org/node/2807

At the moment, I'm making MuseScore accept a netcat pipeline as an alternative to mouse/keyboard/MIDI device.


Comments

And what about using Jack as the socket server which then forwards the MIDI in to MuseScore. I don't know whether either Jack, either MuseScore is up to that job.

Regarding the plugin framework, there was an interesting post yesterday from Miwarre.

In reply to by Thomas

Jack is a bigger question mark as I'm on windows. : /
I'm hoping that this approach might avoid baggage like that.

I am able to add the notes. But the GUI isn't paying attention to display them.

It's a bit discouraging that both A and B are examples on the todo list.
But maybe I overlooked some Qt func as a roundabout solution? A list of all existing top-level windows perhaps?

In reply to by Vhati

I got the main window. Still need to tell it to refresh the score.

      var windowList = QApplication.topLevelWidgets();
      mainWin = null;
      for (i=0; i < windowList.length; i++) {
        if (windowList[i].toString() == "QMainWindow") {
          if (windowList[i].windowTitle.match("^MuseScore:") != null) {
            mainWin = windowList[i];
            break;
          }
        }
      }
      // Just to show this is working, move in front of the debugger window
      if (mainWin != null) mainWin.raise();

Now to manipulate the mainWin... somehow...
Unless I can tell it to update everything, I may have to hunt for a handle to the specific tab... : /

In reply to by Vhati

      //Include the above mainWin finding block if desired

      score = new Score();
      score.name = "MyReallyUniqueTitle";  //Maybe tack on a random number suffix

      var widgetList = QApplication.allWidgets();
      scoreTabWidget = null;
      myTabIndex = -1;
      for (i=0; i < widgetList.length; i++) {
        if (widgetList[i].toString() == "QTabWidget") {
          //The ancestor check is to be extra anal :)
          if (mainWin == null || mainWin.isAncestorOf(widgetList[i]) == true) {
            for (j=0; j < widgetList[i].count; j++) {
              if (widgetList[i].tabText(j) == score.name) {
                scoreTabWidget = widgetList[i];
                myTabIndex = j;
                break;
              }
            }
          }
        }
      }
      //Update the GUI,
      //  and move the tab to the front if it isn't already
      //
      if (scoreTabWidget != null) scoreTabWidget.currentChanged(myTabIndex);
      print("Set a breakpoint here to watch it work");

      score.appendPart("Violin");
      score.appendMeasures(5);
      print("Set a breakpoint here to watch it work");
      if (scoreTabWidget != null) scoreTabWidget.currentChanged(myTabIndex);

      score.appendMeasures(5);
      print("Set a breakpoint here to watch it work");
      if (scoreTabWidget != null) scoreTabWidget.currentChanged(myTabIndex);

The most obvious sign of success is unlike the current "Create Score" plugin, this switches tabs.
If you enable the debugger and set breakpoints, you'll see the GUI incrementally update, but only after I explicitly tell it to.

The mainWin's probably useful to keep around, to set as the parent of QDialogs and QMessageBoxes.

Do you still have an unanswered question? Please log in first to post your question.