Ir al contenido principal

Ralsina.Me — El sitio web de Roberto Alsina

Publicaciones sobre programming (publicaciones antiguas, página 3)

Using linux without the CLI (Newsforge)

Nice ar­ti­cle by Robin Miller at News­forge.

I agree with most of it, ex­cept for one thing.

The au­thor says "I al­ways con­sid­ered the "scratch your own itch" hack­er ethos an es­sen­tial­ly mas­tur­ba­to­ry thing. It would be like me writ­ing ar­ti­cles I want to read in­stead of ar­ti­cles I think you want to read­."

Well, Robin, ar­ti­cles and code are ex­treme­ly dif­fer­ent things. For one thing, ar­ti­cles are 100% use­les for the au­thor, un­less some­one else reads them, whicle code can be 100% use­ful for the au­thor even if noone else has tried it.

I would say it´s like com­par­ing ap­ples and or­anges, ex­cep­t... well, both are fruits and we com­pare them when­ev­er we choose what fruit to buy. This is a less com­pa­ra­ble pair.

For ex­am­ple, I am prob­a­bly the on­ly us­er of KRsN in the world. But it is use­ful for me. It saves me al­most an hour a day, so I wrote it.

On the oth­er hand, I will con­tra­dict my­self: ar­ti­cles al­most noone reads (like this one ;-) are use­ful for shap­ing one´s mind, al­though that´s not a fre­quent goal.

On the grip­ping hand[1], mas­tur­ba­tion is good, dude. Don´t slam it un­less you have nev­er done it. And if you have nev­er done it, don´t slam what you don´t know ;-)

In fac­t, pro­gram­ming be­cause it itch­es is... well, it´s like scratch­ing. It may even be bad for you, but don´t tell me it does­n´t feel good.

[1] One geek cred­it to the one who catch­es the ref­er­ence.

Confused by QMimeSourceFactory

Ok, here it goes. If you are not flu­ent in Qt pro­gram­ming the fol­low­ing en­try will make no sense what­so­ev­er :-)

If you set the con­tents of a QTextBrowser, and the con­tent is HTM­L, it will call its QMime­Source­Fac­to­ry's data() method to get MimeOb­jects rep­re­sent­ing, for ex­am­ple, im­ages in the HTM­L.

So far so good.

How­ev­er, I am mist­i­fied by this: While it's do­ing that, you can change the con­tents, and it will go along it's mer­ry way, ex­cept that old data() calls are still in progress.

In oth­er word­s, it acts as if it's mul­ti­thread­ed. Usu­al­ly, in Qt, this is be­cause some­one is call­ing QAp­p::pro­ces­sEv­ents, and then you have mul­ti­ple func­tions run­ning and yield­ing to each oth­er in the Qt event loop.

That is sure­ly what's hap­pene­ing, but... how the hell does one stop the old data() call­s????

The pro­ces­sEv­ents call is not made by me, it's done in­ter­nal­ly by some method in the QTextBrows­er.... so, right now, in KRsN, some­times you are down­load­ing im­ages for old stuff you saw min­utes ago!

Post-facto inheritance

Now, I did­n't ex­pect this to work at al­l!

A QlistView is a sort of tree wid­get, and is drag&­drop en­abled.

The trick is, you have to reim­ple­ment dragOb­jec­t() so it re­turns a drag­gable thingie af­ter you drag some­thing.

But, since I am us­ing de­sign­er to draw the form­s, I have to use a re­al QListView, not a child class.

Co­nun­drum? Cus­tom wid­get in de­sign­er? Not with python!

def myDragObject(self):

re­turn QTextDrag("­some­thing",­self)

self­.tree.__­class__.­dragOb­jec­t=my­DragOb­ject

And that work­s! I know it should work in python, but QListView is im­ple­ment­ed in a C++ mod­ule!

The guys that did PyQt re­al­ly made it well.

Nifty python/xmlrpc thing

Us­ing python, it's triv­ial to turn any mod­ule in­to a XML­R­PC serv­er. So, if you are care­ful writ­ing your app in a mod­u­lar way, you can move the back­end else­where in very lit­tle code.

For ex­am­ple, if I had a mod­ule that has some func­tion­al­i­ty, like this (mod­ule.py):

#Stupid simple module

def  add(a,b):
        return a+b

A pro­gram would use it like this:

import module
print module.add(2,4)

Now, if I move the mod­ule to a re­mote box (server), cre­ate this xml­r­pc serv­er pro­gram in the serv­er (and run it ;-):

#!/usr/bin/env python

#Simple generic XML-RPC server

import module

import SimpleXMLRPCServer

server = SimpleXMLRPCServer.SimpleXMLRPCServer(("localhost", 800
0))

server.register_instance(module)
server.serve_forever()

And this bridge mod­ule in the client (client­mod­ule.py):

import xmlrpclib

server = xmlrpclib.Server('http://remotserver.com:8000')

Now this very slight­ly mod­i­fied ver­sion of our pro­gram works in ex­act­ly the same way as the orig­i­nal:

from clientmodule import server as module

print module.add(2,4)

Of course this has is­sues:

  • It has no se­cu­ri­ty
  • XML­R­PC could in­tro­duce er­rors and the pro­gram does­n't catch them.
  • It could be made even more trans­par­ent with some more python­ing

But any­way, I think it's cute.

Baby steps

Im­ple­ment­ing prop­er up­dat­ing is sim­ple in that send­ing stuff to PyDS is sim­ple. How­ev­er, hav­ing the GUI do the right thing is trick­y:

When you mod­i­fy an en­try and switch to an­oth­er, you have to of­fer a chance to save or dis­card.

If the us­er dis­card­s, you have to go back to the orig­i­nal data, so it must be saved some­where else. And re­mem­ber this:

>>> a={}
>>> b=a
>>> a['x']=1
>>> b['x']
1

Yeah, ob­vi­ous python se­man­tic­s. Lost an hour, though ;-)

What you want to do in­stead is:

b=copy.deepcopy(a)

If he saves, you have to up­load.

Al­so, when he mod­i­fies, you have to up­date the post list re­al­time, so you see a co­her­ent en­ti­ty. Not too hard, but it forces you to despaghet­tize code some­what.


Contents © 2000-2020 Roberto Alsina