View Full Version : How to display string from socket in a textview (gtkpy/quickly)?
UbuKunubi
June 12th, 2012, 06:19 PM
Hello,
I have a working program in python that reads strings from a socket.
Having now worked through the tutorial that comes with
quickly tutorial, I am trying to find how to get the strings from the socket into a textview.
The pure python code that works is:
import os
import socket
import select
import struct
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.connect(("gmail.com",80))
print "This Computers IP Address is "+(s.getsockname()[0])
s.close()
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.bind(("", 8888))
server_socket.listen(5)
print "TCPServer Waiting for client on port 8888"
while 1:
client_socket, address = server_socket.accept()
print "Addr=", address
data = client_socket.recv(512)
print "RECIEVED:" , data
Can anyone help?
All the best,
Ubu
UbuKunubi
June 13th, 2012, 04:25 PM
With pointers from kkantnaik, I've written the following code.
While it runs without error, the data from the socket is not displaying in the text view :(
# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
### BEGIN LICENSE
# This file is in the public domain
### END LICENSE
import gettext
from gettext import gettext as _
gettext.textdomain('jotty')
import os
import socket
import gobject
from gi.repository import GLib # pylint: disable=E0611
from gi.repository import Gtk # pylint: disable=E0611
import logging
logger = logging.getLogger('jotty')
from jotty.SaveDialog import SaveDialog
from jotty.OpenDialog import OpenDialog
from jotty_lib import Window
from jotty.AboutJottyDialog import AboutJottyDialog
from jotty.PreferencesJottyDialog import PreferencesJottyDialog
# See jotty_lib.Window.py for more details about how this class works
class JottyWindow(Window):
__gtype_name__ = "JottyWindow"
def get_data():
""" set up the socket for reading"""
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.bind(("", 8888))
server_socket.listen(5)
return server_socket
def handle_data(source, condition):
"""get the data from the server socket"""
data = source.recv(512)
if len(data) > 0:
return True #run forever
else:
print 'closed'
print 'so get new data...'
#sock = get_file()
gobject.io_add_watch(server_socket, gobject.IO_IN, handle_data)
buff = self.ui.textview1.get_buffer()
buff.set_text(data)
return False # stop looping
def finish_initializing(self, builder): # pylint: disable=E1002
"""Set up the main window"""
super(JottyWindow, self).finish_initializing(builder)
self.AboutDialog = AboutJottyDialog
self.PreferencesDialog = PreferencesJottyDialog
def on_button1_clicked(self, widget, data=None):
print "---------------------------->Button1 was Clicked"
buff = self.ui.textview1.get_buffer()
buff.set_text("The button was Clicked :) ")
def on_mnu_save_activate(self, widget, data=None):
print "save"
saver = SaveDialog()
result = saver.run()
title = saver.title_text
saver.destroy()
if result != Gtk.ResponseType.OK:
return
#get the string
buff = self.ui.textview1.get_buffer()
start_iter = buff.get_start_iter()
end_iter = buff.get_end_iter()
text = buff.get_text(start_iter, end_iter, True)
#create the filename
data_dir = GLib.get_user_data_dir()
jotty_dir = os.path.join(data_dir, "jotty")
filename = os.path.join(jotty_dir, title)
#write the data
GLib.mkdir_with_parents(jotty_dir, 0o700)
GLib.file_set_contents(filename, text)
def on_mnu_open_activate(self, widget, data=None):
print
print "-----> Open clicked from the menu :)"
print
#get the name of the document to open
opener = OpenDialog()
result = opener.run()
filename = opener.selected_file
#close the dialog, and check whether to proceed
opener.destroy()
if result != Gtk.ResponseType.OK:
return
#try to get the data from the file if it exists
try:
success, text = GLib.file_get_contents(filename)
except Exception:
text = ""
#set the UI to display the string
buff = self.ui.textview1.get_buffer()
buff.set_text(text)
print "-------------------> text from file variable is :"+text
def on_mnu_new_activate(self, widget, data=None):
print "file -> New has been clicked on"
self.ui.entry1.set_text("Note Title")
buff = self.ui.textview1.get_buffer()
buff.set_text("")
server_socket = get_data()
gobject.io_add_watch(server_socket, gobject.IO_IN, handle_data)
Im more used to writing straight-line code, so changing to GTK is a bit of leap.
Any comments, suggestions, etc., are welcome.
Regards,
UbuKunubi.
MG&TL
June 14th, 2012, 10:01 AM
Are you actually calling the Gtk mainloop at any point in that code? I'm not familiar with quickly, but you probably should.
http://www.pygtk.org/pygtk2tutorial/ch-GettingStarted.html#sec-HelloWorld
UbuKunubi
June 14th, 2012, 02:38 PM
In the __init__.py file I have the following, and after considering your question I can see that
Gtk.main() is never called because
while 1: never exits.
__init__.py
# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
### BEGIN LICENSE
# This file is in the public domain
### END LICENSE
import optparse
import socket
from gi.repository import GObject
import gettext
from gettext import gettext as _
gettext.textdomain('jotty')
from gi.repository import Gtk # pylint: disable=E0611
from jotty import JottyWindow
from jotty_lib import set_up_logging, get_version
def get_data():
""" set up the socket for reading"""
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.bind(("", 8888))
server_socket.listen(5)
return server_socket
def handle_data(source, condition):
"""get the data from the server socket"""
data = source.recv(512)
if len(data) > 0:
print "############ Data :",data
#sock = get_file()
gobject.io_add_watch(server_socket, gobject.IO_IN, handle_data)
buff = window.ui.textview1.get_buffer()
buff.set_text(data)
def parse_options():
"""Support for command line options"""
parser = optparse.OptionParser(version="%%prog %s" % get_version())
parser.add_option(
"-v", "--verbose", action="count", dest="verbose",
help=_("Show debug messages (-vv debugs jotty_lib also)"))
(options, args) = parser.parse_args()
set_up_logging(options)
def main():
'constructor for your class instances'
parse_options()
# Run the application.
window = JottyWindow.JottyWindow()
print "window assigned to Jotty Window <---------------------------------!"
#server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
#server_socket.bind(("", 8888))
#server_socket.listen(5)
print "Socket is now bound to port 8888 <--------------------------------!"
window.show()
buff = window.ui.textview1.get_buffer()
buff.set_text("READY")
server_socket = get_data()
GObject.io_add_watch(server_socket, GObject.IO_IN, handle_data)
while 1:
client_socket, address = server_socket.accept()
print "Addr=", address
data = client_socket.recv(512)
print "RECIEVED:" , data
Gtk.main()
I am unsure how to execute the code within the while 1: block, I have asked around and have been presented with the following options:
A) write the while out into a class and have the class return the data string.
B) Create a separate thread and pass the data from there.
C) Leave the while thread in a simple pure python program and run it inside a popen command, reading the terminal (stdin), and update the textview from there.
D) Whatever else I have not looked at.
However my main obstacle is my lack of understanding on how to trigger an update from an event which is NOT a UI action.
So if anyone can provide me with pointers its hughly appreciated.
Thanks for your time,
Ubu
MG&TL
June 14th, 2012, 02:53 PM
There's a couple of solutions here, as Gtk.main needs to be called so the interface doesn't lock up.
Either:
-use threading. This isn't easy, as Gtk needs special treatment for threading. If you choose this route, I can offer you some limited help, but you're best off reading online.
-use this (hack) I discovered while solving a similiar problem:
In you main loop (while 1), add this:
while Gtk.events_pending():
Gtk.main_iteration()
...this manually calls Gtk's loop.
UbuKunubi
June 14th, 2012, 03:35 PM
Thanks for your reply :)
I want to do this properly, ideally the completed project will be available for free in the Ubuntu Software Center,so I'd like to learn more about threading please!
MG&TL
June 14th, 2012, 04:10 PM
I tell a lie, you can also use idle_add to update the GUI when the processor has time, which these days, is continuously.
http://ubuntuforums.org/showthread.php?t=1933882
...looks pretty good to me.
Essentially, the GUI's in the main thread, and that spawns worker threads where required.
Hints:
-Don't try and put the GUI in other threads, it's not a good idea. -Also, don't try and access the GUI from other threads either.
Powered by vBulletin® Version 4.2.2 Copyright © 2024 vBulletin Solutions, Inc. All rights reserved.