Re: What is the minimum number of lines to update a gui window without user clicking a button
- From: "L. D. James" <ljames apollo3 com>
- To: Gavin Lambert <gavinl compacsort com>
- Cc: 'gtkmm-list' <gtkmm-list gnome org>
- Subject: Re: What is the minimum number of lines to update a gui window without user clicking a button
- Date: Mon, 12 Aug 2013 00:08:15 -0400
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]