如何从另一个模块修改或向Python中的WebKit发送信号?

时间:2015-06-22 18:46:43

标签: python webkit pygtk

我是Python的新手,没有面向对象的背景。更糟糕的是,我希望能够使用Do Stuff(),因此我正在研究一些在线资源,包括非常有用的“学习Python艰难之路”,以尝试获取概念和实践。我真的可以在一个超出我的技能的项目中使用一些指导。

我正在尝试构建一个程序,该程序使用WebKitGTK启动浏览器会话,并运行一个小型侦听守护程序。我想向服务器发送信号,服务器通过Telnet将命令中继到WebKit实例......现在,页面刷新就足够了。我需要这个是非阻塞的,因此,通过大量的阅读和犯规,这就是我所拥有的:

main.py: - 使用多处理模块启动侦听服务器 - 启动浏览器显示

server.py: - 运行侦听端口以进行Telnet连接的服务器。 'while'循环是我想要处理收到的命令的地方。

display.py: - 创建并运行Webkit实例

我的问题:

如何在'server.py?'中引用WebKit实例?我尝试创建一个定义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()

更新

好的,我把所有内容都放在一个模块中并创建了一个“显示”类,它有“ init ”和“服务器”方法。当我将'hello'传递给服务器时,它会打印一个Display对象地址(“显示对象位于0x7f20e18a7c80 [GtkWindow位于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()

1 个答案:

答案 0 :(得分:0)

您可以使用类来建模窗口(类通常非常有用于实现GUI)并在线程中运行服务器。因此,您可以使用python的threading.Thread。从线程修改Gtk小部件时,您仍需要注意。 Gtk有自己的机制。您只需使用GLib.idle_add(),就不会遇到因并发修改而导致的问题。

(工作结果在编辑过的问题中可见。)