Re: What is the minimum number of lines to update a gui window without user clicking a button



On 08/11/2013 09:41 PM, Gavin Lambert wrote:
      texttoprint +=
              "About to run a number of c++ functions\nand display the
results\n";
      m_refTextBuffer->set_text(texttoprint);
      m_textview.set_buffer(m_refTextBuffer);
This is all fine right up until that last line, which contains a subtle (but
important) bug.

Thanks Gavin I'm glad that your message suggests that I may have done something right. I have tried. I appreciate your pointing out about bugs in gtkmm. I'm sure with my investigation I'll eventually learn about the bugs and try to assist in the debugging of it, as well as other compoentns that fall short.

GTK widgets (and other UI elements of most other GUI frameworks) are
typically not merely thread-unsafe (as most objects are by default: can be
called from any thread provided that they can be guaranteed to not be called
concurrently) but actually thread-bound (can be called only from one
specific thread, typically the one that created them, or a designated "main
thread").
I thought I was communicating in the main thread that created it. With all the complexity of using the gui, it might be a feat that I'm actually able to add a couple of lines to an example and achieve the needed effect, in spite of the tool having known bugs.

I'll keep everything that you mention in mind while I'm programming and try to identify any glitches that I experience and figure out how to report it to the community, or how to use the bug work around that might already be distributed.

It is therefore not permitted to touch m_textview from any thread other than
the main thread, which that last line is doing.  (And then since this is
assigning a reference to the buffer, it then becomes unsafe to further
modify that buffer later in the worker thread.)

In short, while this might appear to work on your machine for this contrived
example, if you run it enough times in enough different environments and
with different workloads (eg. more frequent text updates) it's very likely
to either crash or exhibit other strange behaviour.  So don't do that.

Others have already pointed you at the correct solutions, and as I am not
sufficiently practiced at GTK myself to give you a precise example I can
only reiterate what those others have said.

I thought I was using what others has pointed out. The only components that I thought I wasn't using is the parts that say have difficult or impossible it is. There was some code examples that were presented that either dimmed and became non-responsive, or never gave an update until the application had finished, which weren't usable. I couldn't use those components.

 From your description of what you're trying to do it seems likely that
carrying out the "actual work" on a separate thread is indeed the correct
thing to be doing.  But you can't just play with GUI objects outside of the
GUI thread.  You need to use some method to convey data from one thread to
another (eg. an explicitly thread-safe queue) combined with some way to get
the main thread to wake up and do some processing (eg. Glib::Dispatcher or a
timeout handler).

In your case, I would recommend using a std::queue of text-to-be-added
protected by a mutex (to make it thread-safe) combined with a
Glib::Dispatcher callback that triggers the main thread to dequeue text and
add it to the textview.
I'll respect your suggestions just as well as I hoped I was respecting all the other suggestions, and still trying to have some representation of the needed output (a gui screen update). I'll try to figure out what you're saying and find a way to implement it without actually breaking the operation. If I add other lines and it stops working, I'd have to come back to what is actually working.

At present, I don't know where to begin, except for what I'm already doing, continuing to study and read everything that appears in the maillist... the things in the threads that I create as well as all the other threads, which are not that easy for me to follow. But I'm reading and trying to comprehend all the messages.

(Though again as others have pointed out if your "actual work" is merely
calling a console application or performing file/network/pipe I/O then you
may want to try using the asynchronous I/O helpers instead, to avoid the
extra thread.)
You may not know much about my actual work. Most of the lines I used in this message thread was a line that goes into a function called sleep. Then appends some text to the gui window. I took a function out of my tens of thousands of lines of code that I have been writing over the past 25 years (of which I mentioned had only been represented once) and you are using that to say most of my work. The user as me to post an example with less than 50 lines So I created something to go out and fix some output. Then I wrote that to the gui window, of which I thought was the main thread. I believe you make a big mistake when you refer to most of my work. I hope to have some way to append text to a gui window regardless where a function such as possibly (sleep()) might get the text from. Most of the code that I was given used the function (sleep()). If it gave a return value. Could I update the screen with that return value? I created text after the operation got back from the function sleep() as it that was the return value and updated the gui screen. That is the best representation of my actual work. I thought I was complying in every way with the suggestions that I was getting from the members.


Multithreading is hard (to get correctly, at least -- it's easy to do it
wrong).  Asynchronous is less hard but still confusing until you get used to
the ideas.  It may be worthwhile for you to read up on both of these
concepts independently of GTK, then read how they apply to GTK, then finally
how they apply to your applications.  You're not going to find a quick and
easy solution -- or at least if you do find one and try to use it without
properly understanding it, you're letting yourself in for a world of hurt.


I'll take up your advise just as well as I have been trying to take up the advise of everyone. I hope it's clear that I haven't stopped working and won't. If I learn how to actually implement something different based on your words that works, I'll come back and post it.

I thank you for the comments. But again, your tone appears to suggest that I'm not trying to comply with what everyone is saying. I believe mainly fall short on the component where I go into details trying to explain what I'm trying to do, and almost everyone is telling me that I talk to much. I'll try to compile and use the suggestions that I'm getting, but I can't use the components that immediately fails. I post something that isn't immediately failing, and am told to do something different, of which I don't understand. If you posted an example of the difference that you're referring to I'd actually test it and tell you the results. If it doesn't update a gui screen, it wouldn't be usable. But I'd test it just like I'm trying to test everything else.

I thought that I was following Kjell's suggestion to element that things that I wouldn't be using and use the important one liner that he presented. I'm still working with Kjell's example, trying to figure out how to eliminate everything and add just one blank slate and built from there. I guest as you're suggestion I got it wrong in my manner of eliminating everything by taking the simplest code that only had one thing (the button from the hello world tutorial). I made one change and thought I was adding Kjell's line and following to the letter what I was presented with.

I don't know how to follow the suggestions any closer that what I'm doing.

Since you think everyone is telling me something different, I'll follow your suggestion and reread the thread and keep studying the thread to see where I'm going wrong. I understand I might be missing something, but at present if I can't see it, I can only report on the results and appreciate any further comments.

Kjell said in his message, that everything was already there in the documentation, just not an actual example (a few days ago). So I went back and did as you appear to be suggesting, spent sleepless nights since, reading and studying and actually using what is there.

You appear to be telling me to study and use gtk rather than gtkmm. I fear that if I did that and tried to post something, I might be admonished even more for not using gtkmm which this forum is about, and reinventing the wheel. I'll take your advise and start studying gtk, but I'll be very leery to start creating my own interface when you describe it so complicated that it's broken in gtkmm which has been in the development for a number of years.

I hope that I presented my efforts to comply with everything that I'm presented with, of which I can understand, and continue to work at the same time, and share what I have come up with at this point, based on taking in everything that is being presented. I can't use the parts that I don't understand. I won't stop studying, as you have suggested.

-- L. James

--
L. D. James
ljames apollo3 com
www.apollo3.com/~ljames


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]