Python 使用gui制作irc机器人。断开切换按钮的困难

Python 使用gui制作irc机器人。断开切换按钮的困难,python,python-2.7,pygtk,irc,glade,Python,Python 2.7,Pygtk,Irc,Glade,我只是在学习python,因为我需要它,所以请坚持,因为这段代码会很混乱 因此,我与glade合作为我的客户端twitch irc聊天机器人创建了一个gui,并在工具栏中创建了这个切换按钮: <object class="GtkToggleToolButton" id="tool_deploy_toggle"> <property name="use_action_appearance">False</property> <property na

我只是在学习python,因为我需要它,所以请坚持,因为这段代码会很混乱

因此,我与glade合作为我的客户端twitch irc聊天机器人创建了一个gui,并在工具栏中创建了这个切换按钮:

<object class="GtkToggleToolButton" id="tool_deploy_toggle">
  <property name="use_action_appearance">False</property>
  <property name="visible">True</property>
  <property name="can_focus">False</property>
  <property name="label" translatable="yes">Connect</property>
  <property name="use_underline">True</property>
  <property name="stock_id">gtk-jump-to</property>
  <signal name="toggled" handler="on_tool_deploy_toggle_toggled" swapped="no"/>
</object>
然后我希望它继续循环此代码(忽略葡萄牙语中的注释)(也是的,我知道我的代码不是最好的,我只是在学习):

我希望上面的所有事情都能够在不关闭和重新打开脚本的情况下完成

所以问题是我不能这么做

如果我将主脚本(连接来自GUI的按钮信号的脚本)放入,它将中断gtk主循环,GUI将崩溃


我尝试过使用线程,但我似乎不理解它们。

状态更新我对线程做了更多的研究,从另一篇stackoverflow文章中获得了一个线程示例,并使其正常工作

我创建了这个线程(请注意,
joinRoom(irc,self)
之后,如果连接成功,套接字将设置为非阻塞,否则它将执行一个
循环。clear()
,它将永远不会进入bot主循环,而是直接进入
irc.close()
):

并连接处理程序:

#Handler Connection.#
handlers = {
"on_blasterbot_mainwindow_destroy": gtk.main_quit,
"on_tool_deploy_button_clicked": bot_thread
}
builder.connect_signals(handlers)

#Stuff I know I need but don't know what is for.#
gtk.main()

因此,您的选择是:1)使用已经与mainlop集成的第三方库。2) 重写您的,以使用Gio进行联网(与mainloop集成)。3) 手动将普通套接字与mainloop集成。Twisted是具有GLib mainloop集成并处理IRC的库的一个示例。对于一个简单的机器人来说,这可能是一个不错的选择。我已经对线程进行了足够深入的研究,并从另一篇stackoverflow文章中获得了一个线程示例。有了这些,我就可以让它工作了。但还是要谢谢你帮我。
while True:
    readbuffer = readbuffer + irc.recv(1024)
    temp = string.split(readbuffer, "\n")
    readbuffer = temp.pop()

    for line in temp:
###Essenciais###--------------------------------------------------------------------------------------------------------------------------------------------
#Mostra a linha que e dada pelo servidor de IRC (So pelo sim pelo nao).-----------------------------------------------------------------------
        print (line)
#---------------------------------------------------------------------------------------------------------------------------------------------
#Impede que seja desconectado pelo servidor de IRC.-------------------------------------------------------------------------------------------
        if line.startswith('PING'):
            irc.send('PONG ' + line.split( ) [ 1 ] + '\r\n')
            print "PONGED BACK"
            break
#---------------------------------------------------------------------------------------------------------------------------------------------
#Le a linha que e dada pelo servidor de IRC e devevole o utilizador, a menssagem e o canal. Volta se algum for nulo.--------------------------
        user = getUser(line)
        message = getMessage(line)
        channel = getChannel(line)
        moderator = getModerator(line)
        if channel == None or user == None or message == None:
            break
#---------------------------------------------------------------------------------------------------------------------------------------------
#Formata o texto e mostra mostra na consola.--------------------------------------------------------------------------------------------------
        print channel + ": " + user + " > " + message
#---------------------------------------------------------------------------------------------------------------------------------------------
###Essenciais END###----------------------------------------------------------------------------------------------------------------------------------------

        if message == "!commands\r":
            globalcommandskeys = str(globalcommands.keys()).replace("[", "").replace("]", "")
            moderatorcommandskeys = str(moderatorcommands.keys()).replace("[", "").replace("]", "")
            channelcommandskeys = str(commands.keys()).replace("[", "").replace("]", "")
            sendMessage(irc, "Global commands: " + globalcommandskeys)
            if channelcommandskeys != "":
                sendMessage(irc, "Channel specific commands: " + channelcommandskeys )
            if moderator == "1":
                sendMessage(irc, "Moderator commands: " + moderatorcommandskeys)
            break


        if message.startswith("!addcom ") and (moderator == "1" or user == channel):
            if message.count(" ") >= 2:
                try:
                    commandadd = command_add(message)
                    answer = command_answer(message)
                except IndexError:
                    sendMessage(irc, user + " the command is used this way !addcom !<command_name> <command_answer>")
                    break
                if globalcommands.has_key(commandadd) or moderatorcommands.has_key(commandadd):
                    sendMessage(irc, user + " you can't add the command " + '"!' + commandadd + '" !!!')
                    break
                try:
                    commands[commandadd]
                except KeyError:
                    commands[commandadd] = answer
                    sendMessage(irc, user + " the command !" + commandadd + " has been added!!!")
                    with file("commands.json","w") as commandsDatabase:
                        json.dump(commands, commandsDatabase)
                    break
                sendMessage(irc, user + " the command you tried to add alredy exists!!!")
                break
            sendMessage(irc, user + " the command is used this way !addcom !<command_name> <command_answer>")
            break

        if message.startswith("!delcom ") and (moderator == "1" or user == channel):
            if message.count(" ") == 1:
                try:
                    commanddel = command_del(message)
                except IndexError:
                    sendMessage(irc, user + "the command is used this way !delcom !<command_name>")
                    break
                if globalcommands.has_key(commanddel) or moderatorcommands.has_key(commanddel):
                    sendMessage(irc, user + " you can't delete the command " + '"!' + commanddel + '" !!!')
                    break
                try:
                    commands[commanddel]
                except KeyError:
                    sendMessage(irc, user + " the command you tried to delete doens't exist!!!")
                    break
                del commands[commanddel]
                sendMessage(irc, user + " the command !" + commanddel + " has been deleted!!!")
                with file("commands.json","w") as commandsDatabase:
                    json.dump(commands, commandsDatabase)
                break
            sendMessage(irc, user + " the command is used this way !delcom !<command_name>")
            break

        if message.startswith("!"):
            if cooldown() == True:
                if message.count(" ") == 0:
                    try:
                        command = getCommand(message)
                    except IndexError:
                        break
                    try:
                        sendMessage(irc, commands[command])
                        now = time.time()
                        cooldown = lambda: time.time() > now + 10
                    except KeyError:
                        break
                if message.count(" ") == 1:
                    try:
                        command = getCommandSpaced(message)
                        target = getString(message)
                    except IndexError:
                        break
                    try:
                        replacing = commands[command]
                        sendMessage(irc, replacing.replace("$target", target))
                        now = time.time()
                        cooldown = lambda: time.time() > now + 10
                    except KeyError:
                        break
                break
irc.close()
gobject.threads_init()

class T(threading.Thread):
    loop = threading.Event()
    stop = False

    def start(self, *args):
        super(T, self).start()

    def run(self):
        while not self.stop:
            #Waits for button to be clicked.#
            self.loop.wait()

            #Bot Startup sequence.#
            deploy_button.set_label('Disconnect')
            irc = botOpenSocket()
            joinRoom(irc, self)
            readbuffer = ""
            irc.send("CAP REQ :twitch.tv/membership\r\n")
            irc.send("CAP REQ :twitch.tv/commands\r\n")
            irc.send("CAP REQ :twitch.tv/tags\r\n")

            try:
                with file("commands.json","r") as commandsDatabase:
                    commands = json.load(commandsDatabase)
            except IOError:
                commands = {}
                with file("commands.json","w") as commandsDatabase:
                    json.dump(commands, commandsDatabase)

            globalcommands = {"spank": True}
            moderatorcommands = {"addcom": True, "delcom": True}
            stringspace = " "
            nothing = ""
            now = time.time()
            cooldown = lambda: time.time() > now + 1

            #Keeps reading chat and awsering.#
            while self.loop.is_set():
                try:
                    readbuffer = readbuffer + irc.recv(1024)
                    temp = string.split(readbuffer, "\n")
                    readbuffer = temp.pop()
                except:
                    pass
                else:
                    for line in temp:
                ###Essenciais###--------------------------------------------------------------------------------------------------------------------------------------------
                #Mostra a linha que e dada pelo servidor de IRC (So pelo sim pelo nao).-----------------------------------------------------------------------
                        print (line)
                #---------------------------------------------------------------------------------------------------------------------------------------------
                #Impede que seja desconectado pelo servidor de IRC.-------------------------------------------------------------------------------------------
                        if line.startswith('PING'):
                            irc.send('PONG ' + line.split( ) [ 1 ] + '\r\n')
                            print "PONGED BACK"
                            break
                #---------------------------------------------------------------------------------------------------------------------------------------------
                #Le a linha que e dada pelo servidor de IRC e devevole o utilizador, a menssagem e o canal. Volta se algum for nulo.--------------------------
                        user = getUser(line)
                        message = getMessage(line)
                        channel = getChannel(line)
                        moderator = getModerator(line)
                        if channel == None or user == None or message == None:
                            break
                #---------------------------------------------------------------------------------------------------------------------------------------------
                #Formata o texto e mostra mostra na consola.--------------------------------------------------------------------------------------------------
                        print channel + ": " + user + " > " + message
                #---------------------------------------------------------------------------------------------------------------------------------------------
                ###Essenciais END###----------------------------------------------------------------------------------------------------------------------------------------

                        if message == "!commands\r":
                            globalcommandskeys = str(globalcommands.keys()).replace("[", "").replace("]", "")
                            moderatorcommandskeys = str(moderatorcommands.keys()).replace("[", "").replace("]", "")
                            channelcommandskeys = str(commands.keys()).replace("[", "").replace("]", "")
                            sendMessage(irc, "Global commands: " + globalcommandskeys)
                            if channelcommandskeys != "":
                                sendMessage(irc, "Channel specific commands: " + channelcommandskeys )
                            if moderator == "1":
                                sendMessage(irc, "Moderator commands: " + moderatorcommandskeys)
                            break


                        if message.startswith("!addcom ") and (moderator == "1" or user == channel):
                            if message.count(" ") >= 2:
                                try:
                                    commandadd = command_add(message)
                                    answer = command_answer(message)
                                except IndexError:
                                    sendMessage(irc, user + " the command is used this way !addcom !<command_name> <command_answer>")
                                    break
                                if globalcommands.has_key(commandadd) or moderatorcommands.has_key(commandadd):
                                    sendMessage(irc, user + " you can't add the command " + '"!' + commandadd + '" !!!')
                                    break
                                try:
                                    commands[commandadd]
                                except KeyError:
                                    commands[commandadd] = answer
                                    sendMessage(irc, user + " the command !" + commandadd + " has been added!!!")
                                    with file("commands.json","w") as commandsDatabase:
                                        json.dump(commands, commandsDatabase)
                                    break
                                sendMessage(irc, user + " the command you tried to add alredy exists!!!")
                                break
                            sendMessage(irc, user + " the command is used this way !addcom !<command_name> <command_answer>")
                            break

                        if message.startswith("!delcom ") and (moderator == "1" or user == channel):
                            if message.count(" ") == 1:
                                try:
                                    commanddel = command_del(message)
                                except IndexError:
                                    sendMessage(irc, user + "the command is used this way !delcom !<command_name>")
                                    break
                                if globalcommands.has_key(commanddel) or moderatorcommands.has_key(commanddel):
                                    sendMessage(irc, user + " you can't delete the command " + '"!' + commanddel + '" !!!')
                                    break
                                try:
                                    commands[commanddel]
                                except KeyError:
                                    sendMessage(irc, user + " the command you tried to delete doens't exist!!!")
                                    break
                                del commands[commanddel]
                                sendMessage(irc, user + " the command !" + commanddel + " has been deleted!!!")
                                with file("commands.json","w") as commandsDatabase:
                                    json.dump(commands, commandsDatabase)
                                break
                            sendMessage(irc, user + " the command is used this way !delcom !<command_name>")
                            break

                        if message.startswith("!"):
                            if cooldown() == True:
                                if message.count(" ") == 0:
                                    try:
                                        command = getCommand(message)
                                    except IndexError:
                                        break
                                    try:
                                        sendMessage(irc, commands[command])
                                        now = time.time()
                                        cooldown = lambda: time.time() > now + 10
                                    except KeyError:
                                        break
                                if message.count(" ") == 1:
                                    try:
                                        command = getCommandSpaced(message)
                                        target = getString(message)
                                    except IndexError:
                                        break
                                    try:
                                        replacing = commands[command]
                                        sendMessage(irc, replacing.replace("$target", target))
                                        now = time.time()
                                        cooldown = lambda: time.time() > now + 10
                                    except KeyError:
                                        break
                                break

            #When button is clicked again do the shutdown sequence.#
            print "coming here"
            irc.close()
            deploy_button.set_label('Connect')

            #Waits for 0.1 seconds before going to the top again, just to be sure.#
            time.sleep(0.1)
<object class="GtkToolButton" id="tool_deploy_button">
 <property name="use_action_appearance">False</property>
 <property name="visible">True</property>
 <property name="can_focus">False</property>
 <property name="label" translatable="yes">Connect</property>
 <property name="use_underline">True</property>
 <property name="stock_id">gtk-jump-to</property>
 <signal name="clicked" handler="on_tool_deploy_button_clicked" swapped="no"/>
</object>
#Defines builder and glade file.#
builder = gtk.Builder()
builder.add_from_file("GUI.glade")

#Gets the main widow and shows it.#
main_Window = builder.get_object("blasterbot_mainwindow")
main_Window.show_all()
#Gets some buttons.#
deploy_button = builder.get_object("tool_deploy_button")

#Starts the thread and the main loop.#
thread = T()
def bot_thread(*args):
    if not thread.is_alive():
        thread.start()
        thread.loop.set()
        #deploy_button.set_label('Disconnect') - Old Sutff
        return

    if thread.loop.is_set():
        thread.loop.clear()
        #deploy_button.set_label('Connect') - Old Sutff
    else:
        thread.loop.set()
        #deploy_button.set_label('Disconnect') - Old Sutff
#Handler Connection.#
handlers = {
"on_blasterbot_mainwindow_destroy": gtk.main_quit,
"on_tool_deploy_button_clicked": bot_thread
}
builder.connect_signals(handlers)

#Stuff I know I need but don't know what is for.#
gtk.main()