2015-06-22 51 views
2

我對Python很陌生,沒有面向對象的背景。更糟的是,我希望能夠做到Stuff(),所以我正在通過一些在線資源,包括非常有幫助的「Learn Python Hard Way」來嘗試獲取概念和實踐。我真的可以在目前超出我的技能的項目中使用一些指導。如何從另一個模塊修改或發送信號到Python中的WebKit?

我試圖建立一個程序,使用WebKitGTK啓動瀏覽器會話,並且還運行一個小的監聽守護進程。我想向服務器發送信號,服務器通過Telnet將命令傳遞給WebKit實例......目前,頁面刷新就足夠了。我需要這是無阻塞的,所以,通過噸的閱讀和犯規,這是我有:

main.py: - 開始使用多模塊 監聽服務器 - 啓動瀏覽器顯示

server.py: - 運行監聽Telnet連接的端口的服務器。 'while'循環是我想要處理收到的命令的地方。

display.py: - 創建並運行WebKit的實例

我的問題:

我如何引用內WebKit的實例「server.py?我嘗試創建一個定義GTK/WebKit對象的全局模塊,然後在'server.listener'中進行訪問,但是我迷失在如何發送信號的過程中。

我知道這不是整潔或有效的,但我的代碼如下。感謝您指點我正確的方向。

############################ 
# main.py 
############################ 

import multiprocessing 
import server 
import display 

if __name__ == '__main__': 
    serv = multiprocessing.Process(name='serverproc', target=server.listener) 
    serv.start() 
    display.browser() 


############################ 
# server.py 
############################ 

import socket 
import sys 
import gtk 


def listener(): 

    HOST = '' 
    PORT = 8089 

    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
    sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) 

    try: 
     sock.bind((HOST, PORT)) 
    except socket.error as msg: 
     print 'Failed to bind. Error: ' + str(msg[0]) + ' Message ' + msg[1] 
     sys.exit() 

    print 'Socket bound' 
    sock.listen(10) 
    print 'Socket listening' 

    while True: 

     conn, address = sock.accept() 
     print 'Connected with ' + address[0] + ':' + str(address[1]) 

     data = conn.recv(64).strip() 
     print 'Received: ' + data + '\n' 

     if not data: 
      break 

     ''' 
     This is where I'd like to be able to send a page refresh signal to the 
     Webkit instance: 
     ''' 
     if data == 'restart': 
      print 'Attempting to restart' 
      break 

     conn.close() 

    conn.close() 
    sock.close() 


############################ 
# display.py 
############################ 

import gtk 
import webkit 
import gtk.gdk as GDK 

def browser(): 

    width = 500 
    height = 800 

    w = gtk.Window() 
    w.connect("destroy", gtk.main_quit) 

    w.set_title("Browser") 
    w.resize(width,height) 
    w.set_keep_above(True) 
    w.set_decorated(False) 

    client = webkit.WebView() 
    client.open('http://127.0.0.1/index.php') 
    client.set_editable(False) 
    client.set_size_request(width, height) 

    w.add(client) 
    w.show_all() 

    gtk.main() 

UPDATE:

好吧,我把一切都放在一個單獨的模塊中,並創建了一個類, 「顯示」,其中有 '初始化' 和 '服務器' 的方法。當我向服務器傳遞'hello'時,它會打印一個Display對象地址(「Display object at 0x7f20e18a7c80 [GtkWindow at 0x23850e0]」),但我不明白爲什麼URL在webkit實例中沒有真正改變。有人可以幫忙嗎?這裏是我更新的代碼:

############################ 
# display.py 
############################ 

import os 
import gtk, gobject 
import webkit 
import socket 
import multiprocessing 

# ================================================= # 

class Display(gtk.Window): 

    def __init__(self): 

     w = 600 
     h = 800 

     gtk.Window.__init__(self) 
     self.set_default_size(w, h) 
     self.browser = webkit.WebView() 
     self.browser.set_size_request(w, h) 

     self.add(self.browser) 
     self.connect('destroy', gtk.main_quit) 

     self.browser.open('http://127.0.0.1/index.php') 
     self.show_all() 

    def server(self): 

     sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
     sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) 
     sock.bind(('127.0.0.1', 8089)) 
     sock.listen(5) 

     while True: 

      conn, address = sock.accept() 
      data = conn.recv(64).strip() 

      if data == 'hello': 
       print self 
       self.browser.open('http://127.0.0.1/newpage.php') 

      conn.close() 

     conn.close() 
     sock.close() 


# ================================================= # 

if __name__ == "__main__": 

    b = Display() 

    serv = multiprocessing.Process(name='serverproc', target=b.server) 
    serv.start() 

    gtk.main() 

SOLUTION:

完成的緣故,這裏的完整的解決方案(是的,我對Python的2.7.9)。

############################ 
# display.py 
############################ 

import os 
import gtk, gobject 
import webkit 
import socket 
import glib 
import threading 

# ================================================= # 

class Display(gtk.Window): 

    def __init__(self): 

     w = 600 
     h = 800 

     gtk.Window.__init__(self) 
     self.set_default_size(w, h) 
     self.browser = webkit.WebView() 
     self.browser.set_size_request(w, h) 

     self.add(self.browser) 
     self.connect('destroy', gtk.main_quit) 

     self.browser.open('http://127.0.0.1/index.php') 
     self.show_all() 

    def server(self): 

     sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
     sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) 
     sock.bind(('127.0.0.1', 8089)) 
     sock.listen(5) 


     while True: 

      conn, address = sock.accept() 
      data = conn.recv(64).strip() 

      if data == 'hello': 
       print self 
       glib.idle_add(self.browser.open, 'http://127.0.0.1/newpage.php') 

      conn.close() 

     conn.close() 
     sock.close() 


# ================================================= # 

if __name__ == "__main__": 

    b = Display() 

    serv = threading.Thread(name='serverproc', target=b.server) 
    serv.start() 

    gtk.main() 
+0

您可以創建瀏覽器類(而不是函數),創建一個對象並將其傳遞給「偵聽器」函數。 – elya5

+0

我目前正在學習有關課程,所以一旦我取得了一些有益的進展,我會回到這裏。我感謝你的指導! – erzlaute

+0

我發佈了一個使用你的建議的修改版本,我可以看到Webkit實例存在,如果我打印到控制檯。不過,我仍然無法修改它,並且我不知道是否需要在某處撥打額外的電話或如何提交更新。任何指針? – erzlaute

回答

0

您可以使用一個類來建模窗口(類通常對於實現GUI非常有用)並在線程中運行服務器。因此,您可以使用python的threading.Thread。當您從線程修改Gtk窗口小部件時,您仍然需要注意。 Gtk有它自己的機制。您可以簡單地使用GLib.idle_add(),並且不會遇到由同時修改引起的問題。

(工作結果在編輯的問題中可見。)

相關問題