如何生成浏览器

发布于 2024-09-16 20:01:33 字数 1976 浏览 5 评论 0原文

我正在基于 irc.IRCClient 和 pygtk 用 python 开发一个 irc 客户端,我使用了正确的反应器,一切正常。 现在我会在单击 URL 时启动浏览器... 更好的选择是使用 xdg-open,它运行配置的默认浏览器(在免费桌面兼容的 DE 中)。 该 URL 在 gtk 按钮按下事件中选取。 我已经尝试了所有我能想到的可能性,但我的CPU 一直处于100%。 以下是我尝试过的各种方法,仅使用reactor.spawnProcess似乎很有希望,因为在浏览器打开之前一切都很好,当关闭它时CPU会达到100%。所有其他 CPU 很快就会跳到 100% 并保持不变。 直接启动浏览器不会改变任何东西。 我做错了什么?

python 2.6.5 - 扭曲10.1.0 - pygtk 2.16.0

Marco

def on_click(self, b):
    .....
    .....
    if data:
        url = self.urls[int(data)]

        # 100% cpu forever
        browser = utils.getProcessValue('/usr/bin/xdg-open', [url,], os.environ)
        browser.addCallback(self.printExitValue)

        # 100% cpu after closing browser 
        xdgProcess = XDGProcessProtocol()
        reactor.spawnProcess(xdgProcess, '/usr/bin/xdg-open', ['/usr/bin/xdg-open', url], os.environ )    

        # 100% cpu forever
        os.system('xdg-open %s' % url)

        # 100% cpu forever
        os.spawnl(os.P_NOWAIT, '/usr/bin/xdg-open', '/usr/bin/xdg-open', url)

        # 100% cpu forever    
        reactor.callInThread(self.browser, url)

        return 0

def printExitValue(self, val):
    print 'xdg-open %d' % val

def browser(self, url):
    os.spawnl(os.P_NOWAIT, '/usr/bin/xdg-open', '/usr/bin/xdg-open', url)

类 XDGProcessProtocol(protocol.ProcessProtocol):

def __init__(self):
    self.data = ''

def connectionMade(self):
    pass

def outReceived(self, data):
    self.data = self.data + data

def errReceived(self, data):
    self.data = self.data + data

def inConnectionLost(self):
    pass

def outConnectionLost(self):
    print self.data

def errConnectionLost(self):
    pass

def processExited(self, reason):
    print "processExited, status %d" % (reason.value.exitCode,)

def processEnded(self, reason):
    print "processEnded, status %d" % (reason.value.exitCode,)
    print "quitting"

I'm developing a irc client in python based on irc.IRCClient and pygtk, I'm using the correct reactor and all works fine.
Now I would launch a browser when clicking a Url...
The better choice is to use xdg-open which runs the configured default browser (in a free desktop compliant DE).
The url is picked in a gtk button-press-event.
I have tried all possibilities I can figure out but ever I got the cpu at 100%.
Below are the various ways I tried, only using reactor.spawnProcess seems promising because until the browser is open all is fine, when closing it the cpu goes to 100%. All others the cpu jump at 100% soon and stay.
Launching the browser directly don't change anything.
What I'm doing wrong ?

python 2.6.5 - twisted 10.1.0 - pygtk 2.16.0

Marco

def on_click(self, b):
    .....
    .....
    if data:
        url = self.urls[int(data)]

        # 100% cpu forever
        browser = utils.getProcessValue('/usr/bin/xdg-open', [url,], os.environ)
        browser.addCallback(self.printExitValue)

        # 100% cpu after closing browser 
        xdgProcess = XDGProcessProtocol()
        reactor.spawnProcess(xdgProcess, '/usr/bin/xdg-open', ['/usr/bin/xdg-open', url], os.environ )    

        # 100% cpu forever
        os.system('xdg-open %s' % url)

        # 100% cpu forever
        os.spawnl(os.P_NOWAIT, '/usr/bin/xdg-open', '/usr/bin/xdg-open', url)

        # 100% cpu forever    
        reactor.callInThread(self.browser, url)

        return 0

def printExitValue(self, val):
    print 'xdg-open %d' % val

def browser(self, url):
    os.spawnl(os.P_NOWAIT, '/usr/bin/xdg-open', '/usr/bin/xdg-open', url)

class XDGProcessProtocol(protocol.ProcessProtocol):

def __init__(self):
    self.data = ''

def connectionMade(self):
    pass

def outReceived(self, data):
    self.data = self.data + data

def errReceived(self, data):
    self.data = self.data + data

def inConnectionLost(self):
    pass

def outConnectionLost(self):
    print self.data

def errConnectionLost(self):
    pass

def processExited(self, reason):
    print "processExited, status %d" % (reason.value.exitCode,)

def processEnded(self, reason):
    print "processEnded, status %d" % (reason.value.exitCode,)
    print "quitting"

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

撩发小公举 2024-09-23 20:01:33

关闭主题:
这是 pygobject 和 pygtk 中的一个错误,SIGCHLD 处理程序进入无限循环。
中修复

这已在 pygobject-2.21,0 和 pygtk-2.17.0 marco

To close the topic:
it is a bug in both pygobject and pygtk, the SIGCHLD handler enters a endless loop.
This was fixed in pygobject-2.21,0 and pygtk-2.17.0

marco

久伴你 2024-09-23 20:01:33

你可以使用这个:

import webbrowser

webbrowser.open("http://www.google.it/")

You can use this:

import webbrowser

webbrowser.open("http://www.google.it/")
悲念泪 2024-09-23 20:01:33

webbrowser 模块可能是您正在寻找的吗?它是 python 标准库的一部分。

is the webbrowser module perhaps what you're looking for? It's part of python's standard library.

一城柳絮吹成雪 2024-09-23 20:01:33

这是一个有效(和失败)的示例。

我调整了您的 irclogbot.py 以在 pygtk 应用程序中运行。

Sys.argv[1] 是 irc 服务器的 url。

在 on_click 方法中更改可执行路径以适合您所拥有的浏览器。

浏览器打开页面关闭页面后,CPU利用率跃升至100%。

#!/usr/bin/env python
# -*- coding: utf-8 -*-

# Copyright (c) 2001-2009 Twisted Matrix Laboratories.
# See LICENSE for details.
import gobject
import pygtk
import gtk

# twisted imports
from twisted.internet import gtk2reactor
gtk2reactor.install()
from twisted.words.protocols import irc
from twisted.internet import reactor, protocol
from twisted.python import log

# system imports
import time, sys

class MessageLogger:
    """
    An independent logger class (because separation of application
    and protocol logic is a good thing).
    """
    def __init__(self, file):
        self.file = file

    def log(self, message):
        """Write a message to the file."""
        timestamp = time.strftime("[%H:%M:%S]", time.localtime(time.time()))
        self.file.write('%s %s\n' % (timestamp, message))
        self.file.flush()

    def close(self):
        self.file.close()


class LogBot(irc.IRCClient):
    """A logging IRC bot."""

    nickname = "twistedbot"

    def connectionMade(self):
        irc.IRCClient.connectionMade(self)
        self.logger = MessageLogger(open(self.factory.filename, "a"))
        self.logger.log("[connected at %s]" % 
                        time.asctime(time.localtime(time.time())))

    def connectionLost(self, reason):
        irc.IRCClient.connectionLost(self, reason)
        self.logger.log("[disconnected at %s]" % 
                        time.asctime(time.localtime(time.time())))
        self.logger.close()


    # callbacks for events

    def signedOn(self):
        """Called when bot has succesfully signed on to server."""
        self.join(self.factory.channel)

    def joined(self, channel):
        """This will get called when the bot joins the channel."""
        self.logger.log("[I have joined %s]" % channel)

    def privmsg(self, user, channel, msg):
        """This will get called when the bot receives a message."""
        user = user.split('!', 1)[0]
        self.logger.log("<%s> %s" % (user, msg))

        # Check to see if they're sending me a private message
        if channel == self.nickname:
            msg = "It isn't nice to whisper!  Play nice with the group."
            self.msg(user, msg)
            return

        # Otherwise check to see if it is a message directed at me
        if msg.startswith(self.nickname + ":"):
            msg = "%s: I am a log bot" % user
            self.msg(channel, msg)
            self.logger.log("<%s> %s" % (self.nickname, msg))

    def action(self, user, channel, msg):
        """This will get called when the bot sees someone do an action."""
        user = user.split('!', 1)[0]
        self.logger.log("* %s %s" % (user, msg))

    # irc callbacks

    def irc_NICK(self, prefix, params):
        """Called when an IRC user changes their nickname."""
        old_nick = prefix.split('!')[0]
        new_nick = params[0]
        self.logger.log("%s is now known as %s" % (old_nick, new_nick))


    # For fun, override the method that determines how a nickname is changed on
    # collisions. The default method appends an underscore.
    def alterCollidedNick(self, nickname):
        """
        Generate an altered version of a nickname that caused a collision in an
        effort to create an unused related name for subsequent registration.
        """
        return nickname + '^'



class LogBotFactory(protocol.ClientFactory):
    """A factory for LogBots.

    A new protocol instance will be created each time we connect to the server.
    """

    # the class of the protocol to build when new connection is made
    protocol = LogBot

    def __init__(self, channel, filename):
        self.channel = channel
        self.filename = filename

    def clientConnectionLost(self, connector, reason):
        """If we get disconnected, reconnect to server."""
        connector.connect()

    def clientConnectionFailed(self, connector, reason):
        print "connection failed:", reason
        reactor.stop()

class GUI(object):
    def __init__(self):
        self.mw = gtk.Window()
        self.mw.connect('destroy', self.quit)
        bt = gtk.Button('Run browser')
        bt.connect('clicked', self.on_click)
        frame = gtk.Frame('Click me')
        frame.add(bt)
        self.mw.add(frame)
        self.mw.show_all()
        f = LogBotFactory('#prova', 'botlog.txt')
        # connect factory to this host and port
        reactor.connectTCP(sys.argv[1], 6667, f)
        reactor.run()

    def on_click(self, b):
        url = 'http://www.gentoo.org'
        xdgProcess = XDGProcessProtocol()
        #####################################################
        # change the executable path of the browser you have
        #####################################################
        reactor.spawnProcess(xdgProcess, '/usr/bin/midori', ['/usr/bin/midori', url], None)    
        print 'clicked'

    def quit(self, w):
        print 'closeapp'
        try:
            reactor.stop()
        except:
            pass
        gtk.main_quit()

class XDGProcessProtocol(protocol.ProcessProtocol):
    def __init__(self):
        self.data = ''

    def connectionMade(self):
        pass

    def outReceived(self, data):
        self.data = self.data + data

    def errReceived(self, data):
        self.data = self.data + data
    def inConnectionLost(self):
        pass

    def outConnectionLost(self):
        print "outConnectionLost! The child closed their stdout!"
        print self.data

    def errConnectionLost(self):
        pass

    def processExited(self, reason):
        print "processExited, status %d" % (reason.value.exitCode,)

    def processEnded(self, reason):
        print "processEnded, status %d" % (reason.value.exitCode,)
        print "quitting"

if __name__ == '__main__':
    #########################################    
    # sys.argv[1] is the url of the irc server    
    #########################################
    # initialize logging
    log.startLogging(sys.stdout)

    GUI()
    gtk.main()

马可

Here is a working (and failing) example.

I adapted your irclogbot.py to run in a pygtk app.

Sys.argv[1] is the url of a irc server.

In the method on_click change the executable path to suit a browser you have.

After the browser opened the page close it, the cpu utilization jump to 100%.

#!/usr/bin/env python
# -*- coding: utf-8 -*-

# Copyright (c) 2001-2009 Twisted Matrix Laboratories.
# See LICENSE for details.
import gobject
import pygtk
import gtk

# twisted imports
from twisted.internet import gtk2reactor
gtk2reactor.install()
from twisted.words.protocols import irc
from twisted.internet import reactor, protocol
from twisted.python import log

# system imports
import time, sys

class MessageLogger:
    """
    An independent logger class (because separation of application
    and protocol logic is a good thing).
    """
    def __init__(self, file):
        self.file = file

    def log(self, message):
        """Write a message to the file."""
        timestamp = time.strftime("[%H:%M:%S]", time.localtime(time.time()))
        self.file.write('%s %s\n' % (timestamp, message))
        self.file.flush()

    def close(self):
        self.file.close()


class LogBot(irc.IRCClient):
    """A logging IRC bot."""

    nickname = "twistedbot"

    def connectionMade(self):
        irc.IRCClient.connectionMade(self)
        self.logger = MessageLogger(open(self.factory.filename, "a"))
        self.logger.log("[connected at %s]" % 
                        time.asctime(time.localtime(time.time())))

    def connectionLost(self, reason):
        irc.IRCClient.connectionLost(self, reason)
        self.logger.log("[disconnected at %s]" % 
                        time.asctime(time.localtime(time.time())))
        self.logger.close()


    # callbacks for events

    def signedOn(self):
        """Called when bot has succesfully signed on to server."""
        self.join(self.factory.channel)

    def joined(self, channel):
        """This will get called when the bot joins the channel."""
        self.logger.log("[I have joined %s]" % channel)

    def privmsg(self, user, channel, msg):
        """This will get called when the bot receives a message."""
        user = user.split('!', 1)[0]
        self.logger.log("<%s> %s" % (user, msg))

        # Check to see if they're sending me a private message
        if channel == self.nickname:
            msg = "It isn't nice to whisper!  Play nice with the group."
            self.msg(user, msg)
            return

        # Otherwise check to see if it is a message directed at me
        if msg.startswith(self.nickname + ":"):
            msg = "%s: I am a log bot" % user
            self.msg(channel, msg)
            self.logger.log("<%s> %s" % (self.nickname, msg))

    def action(self, user, channel, msg):
        """This will get called when the bot sees someone do an action."""
        user = user.split('!', 1)[0]
        self.logger.log("* %s %s" % (user, msg))

    # irc callbacks

    def irc_NICK(self, prefix, params):
        """Called when an IRC user changes their nickname."""
        old_nick = prefix.split('!')[0]
        new_nick = params[0]
        self.logger.log("%s is now known as %s" % (old_nick, new_nick))


    # For fun, override the method that determines how a nickname is changed on
    # collisions. The default method appends an underscore.
    def alterCollidedNick(self, nickname):
        """
        Generate an altered version of a nickname that caused a collision in an
        effort to create an unused related name for subsequent registration.
        """
        return nickname + '^'



class LogBotFactory(protocol.ClientFactory):
    """A factory for LogBots.

    A new protocol instance will be created each time we connect to the server.
    """

    # the class of the protocol to build when new connection is made
    protocol = LogBot

    def __init__(self, channel, filename):
        self.channel = channel
        self.filename = filename

    def clientConnectionLost(self, connector, reason):
        """If we get disconnected, reconnect to server."""
        connector.connect()

    def clientConnectionFailed(self, connector, reason):
        print "connection failed:", reason
        reactor.stop()

class GUI(object):
    def __init__(self):
        self.mw = gtk.Window()
        self.mw.connect('destroy', self.quit)
        bt = gtk.Button('Run browser')
        bt.connect('clicked', self.on_click)
        frame = gtk.Frame('Click me')
        frame.add(bt)
        self.mw.add(frame)
        self.mw.show_all()
        f = LogBotFactory('#prova', 'botlog.txt')
        # connect factory to this host and port
        reactor.connectTCP(sys.argv[1], 6667, f)
        reactor.run()

    def on_click(self, b):
        url = 'http://www.gentoo.org'
        xdgProcess = XDGProcessProtocol()
        #####################################################
        # change the executable path of the browser you have
        #####################################################
        reactor.spawnProcess(xdgProcess, '/usr/bin/midori', ['/usr/bin/midori', url], None)    
        print 'clicked'

    def quit(self, w):
        print 'closeapp'
        try:
            reactor.stop()
        except:
            pass
        gtk.main_quit()

class XDGProcessProtocol(protocol.ProcessProtocol):
    def __init__(self):
        self.data = ''

    def connectionMade(self):
        pass

    def outReceived(self, data):
        self.data = self.data + data

    def errReceived(self, data):
        self.data = self.data + data
    def inConnectionLost(self):
        pass

    def outConnectionLost(self):
        print "outConnectionLost! The child closed their stdout!"
        print self.data

    def errConnectionLost(self):
        pass

    def processExited(self, reason):
        print "processExited, status %d" % (reason.value.exitCode,)

    def processEnded(self, reason):
        print "processEnded, status %d" % (reason.value.exitCode,)
        print "quitting"

if __name__ == '__main__':
    #########################################    
    # sys.argv[1] is the url of the irc server    
    #########################################
    # initialize logging
    log.startLogging(sys.stdout)

    GUI()
    gtk.main()

Marco

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文