[Twisted-Python] qt5 and twisted, reactor already installed, python 2.x
hi, ive got some twisted code that runs on its own and some python code that also runs on its own, now i would like to combine the two, so i added: if __name__ == '__main__': app = QtWidgets.QApplication(sys.argv) # your code to init QtCore import qt5reactor qt5reactor.install() from twisted.internet import reactor to use some qt reactor with twisted. running the qt code with those lines also works. but as soon as i import other code into this one i get: python main_code.py Gtk-Message: Failed to load module "canberra-gtk-module" Traceback (most recent call last): File "main_code.py", line 29, in <module> qt5reactor.install() File "/home/julius/.local/lib/python2.7/site-packages/qt5reactor.py", line 412, in posixinstall installReactor(p) File "/home/julius/.local/lib/python2.7/site-packages/twisted/internet/main.py", line 32, in installReactor raise error.ReactorAlreadyInstalledError("reactor already installed") twisted.internet.error.ReactorAlreadyInstalledError: reactor already installed here is my code: when importing get_main_page i get the error above... import sys from PyQt5 import QtWidgets from untitled import Ui_MainWindow #from webchat import get_main_page class Main(QtWidgets.QMainWindow): def __init__(self): QtWidgets.QMainWindow.__init__(self) self.ui = Ui_MainWindow() self.ui.setupUi(self) self.setupSignals() def button_1_Clicked(self): self.ui.textbox_2.setText(self.ui.textbox_1.text()) def setupSignals(self): #self.ui.textbox_1.textChanged.connect(self.textbox_1_Changed) self.ui.button_1.clicked.connect(self.button_1_Clicked) if __name__ == '__main__': #app = QtWidgets.QApplication(sys.argv) app = QtWidgets.QApplication(sys.argv) # your code to init QtCore import qt5reactor qt5reactor.install() from twisted.internet import reactor print "testing..." #get_main_page() window = Main() window.show() #sys.exit(app.exec_()) def printMe(argument): print argument def lala(): reactor.callLater(5, printMe, '123') lala() reactor.run() webchat.py (containing get_main_page) starts with the lines: from twisted.web.client import Agent, CookieAgent, getPage, HTTPClientFactory from bs4 import BeautifulSoup import json import urllib import random from myglobals import * from twisted.internet.task import LoopingCall how can i get a more "refined" error message, that actually tells me which line is causing the error? because as i said, the line 29 in main_code works when i do not import get_main_page
On Jun 29, 2016, at 15:39, steven meier <commercials24@yahoo.de> wrote:
here is my code: when importing get_main_page i get the error above...
import sys from PyQt5 import QtWidgets from untitled import Ui_MainWindow #from webchat import get_main_page
You have to put the qt5reactor installation at the very top of the very first file that you run. What's happened here is that you imported some Twisted code that did 'from twisted.internet import reactor' at the top level, which unfortunately far too many modules do, before you installed the qt5 reactor. For this and other reasons, you should always put your `if __name__ == '__main__'` block - if you have one at all - at the very top of your script, not the bottom. This blog post may be informative: https://moshez.wordpress.com/2016/06/07/__name__-__main__-considered-harmful... -glyph
On Wed, 2016-06-29 at 16:01 -0700, Glyph wrote:
On Jun 29, 2016, at 15:39, steven meier <commercials24@yahoo.de> wrote:
here is my code: when importing get_main_page i get the error above...
import sys from PyQt5 import QtWidgets from untitled import Ui_MainWindow #from webchat import get_main_page
You have to put the qt5reactor installation at the very top of the very first file that you run. What's happened here is that you imported some Twisted code that did 'from twisted.internet import reactor' at the top level, which unfortunately far too many modules do, before you installed the qt5 reactor.
For this and other reasons, you should always put your `if __name__ == '__main__'` block - if you have one at all - at the very top of your script, not the bottom. This blog post may be informative: https://moshez.wordpress.com/2016/06/07/__name__-__main__-considered-harmful...
-glyph _______________________________________________
thank you for the quick reply, you were right. but because of the qt imports / Main class my file now basically has the line: from webchat import get_main_page at the end with the rest unchanged....but at least it runs
You have to put the qt5reactor installation at the very top of the very first file that you run. What's happened here is that you imported some Twisted code that did 'from twisted.internet import reactor' at the top level, which unfortunately far too many modules do, before you installed the qt5 reactor.
So twisted modules should not at all import the reactor but rely on the user code todo that?
On Jun 30, 2016, at 03:49, steven meier <commercials24@yahoo.de> wrote:
You have to put the qt5reactor installation at the very top of the very first file that you run. What's happened here is that you imported some Twisted code that did 'from twisted.internet import reactor' at the top level, which unfortunately far too many modules do, before you installed the qt5 reactor.
So twisted modules should not at all import the reactor but rely on the user code todo that?
Yes. Unfortunately, lots of places do import the reactor directly today, but we have long since decided that this is a bad way to do things. This is why e.g. react <https://twistedmatrix.com/documents/16.2.0/api/twisted.internet.task.html#react> passes the reactor to your function as a parameter, so you can pass it on down to any other code that needs it. -glyph
Glyph Lefkowitz <glyph@twistedmatrix.com> writes:
Yes. Unfortunately, lots of places do import the reactor directly today, but we have long since decided that this is a bad way to do things. This is why e.g. react <https://twistedmatrix.com/documents/16.2.0/api/twisted.internet.task.h tml#react> passes the reactor to your function as a parameter, so you can pass it on down to any other code that needs it.
As a "casual" user of Twisted, I was somewhat skeptical of this "pass the reactor everywhere" approach -- but I did try to follow this advice in txtorcon, and was rewarded with easy-to-write tests regarding timing, which are (usually) a horror-show *and* I was rewarded with having to think about "do I *really* need the reactor here?". Now, sometimes you can compromise. For example, see my AddrMap class which assigns a "self.scheduler" which is usually just gotten by importing from twisted.internet.reactor -- *but* critically, the tests can re-assign this: https://github.com/meejah/txtorcon/blob/master/test/test_addrmap.py#L109 Ideally, this would have been passed-in via the __init__ but, *shruggy-face*. The point being, you can incrementally upgrade to "the better way". Overall, I'm very sold on accessing "the reactor" via "self dot something" rather than via imports *even if* the only reason ends up being "because testing". It's pretty likely that some random user you've never heard of has a similar use-case to that thing you needed to do in that one test... (I've read this elsewhere, not my idea) If nothing else, it will cause you to pause and consider "how will this thing access the reactor", which will cause you to think about concurrency issues... (Or, contrary-wise, classes which *don't* have a self._reactor definitely do *not* need any thinking about concurrency -- which is also a big win). In any case, my concurrency-hackles raise when I see ".. import reactor". Best to localize these fears to "self._reactor". -- meejah
participants (4)
-
Glyph
-
Glyph Lefkowitz
-
meejah
-
steven meier