Craft your own GUIs with Python and Tkinter

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
all right everyone hopefully by my color schema it shouldn't be too obvious when I started working on these slides mm-hmm so but my name is Bryce entero I am a Desktop Services specialist with Jam software so I'm into a light Tiye Jam and if you ask people around the conference who know me they would actually just say that I was a Casper guy because that's pretty much what I do internally I'm the Casper at Annette jam software working with a few other people on the IT staff well just shout out here to Jason Miller because I forgot my clicker I like the free roam and wave my hands a whole lot so he let me his right there Twitter like a slack LinkedIn those are all the places that you can find me out there on the web so if you need to reach out after the conference that's where I do it just going to save this here you don't need to take notes there's nothing to take notes about because everything that you see in here plus a few extras is out on this github repo and if you haven't gone out and grabbed all this stuff yet thankfully you know Python files and github are really small so I think the AT&T Wi-Fi will hold up if you go out to just download it right now all right and then if you need to run the examples just use that syntax right there on the files front of your on terminal ok so we are here today to talk about TK inter Python TK inter that is the title of this deck there we go Python TK inter gotta remember to click this thing and then really this is all about adding yet another tool to your knowledge arsenal a couple of things that we're not going to be talking about here is convincing you that you should just use this all the time it's not the point of this is you know this is just about sharing knowledge and giving you yet another option for when you have to come up across something and it's definitely not about telling you that you shouldn't use cocoa dialogue anymore or jamp helper if you know if you use jammed helper all right oh okay there we go so TK answer is not a part of Python TK enter is a toolkit it's a cross-platform toolkit it works on Mac it works on Windows it works on Linux and it actually um interfaces directly with the window managers of those operating systems so if you're writing if you import the library into Python and you're writing TK ntarama code that code with a few exceptions here and there will work across platforms it's actually really really widely used in the scientific community you know data data mining in the scientific community they build GUI applications around that stuff for visualization interaction and this is the primary GUI toolkit that they use for that that's where you see it the most all the great things about this is that python Antica inter-are standard on mac OS so i mean like if you have a mac in front of you they're preloaded by apple already so this is a solution where you can run a script and execute code on the machine and you don't have to pre install or pre configure anything it's just there and it also means that if you were to build out a script that popular popped up a GUI for the user to do something with there what you take away from their interaction with that dialog could be executed within the same file also in python so you're keeping it all in one language and in one file slash program and the other thing that some people don't really think about this too often but the other thing is that with a lot of other solutions the user clicks on something and the GUI closes and you return something and then you either have to parse a little is returned or you have to like grab the exit code and then build logic after that and maybe have to represent a GUI to them but going this route you don't have to have the GUI closed until you wanted to which means they could click on something and what they clicked on is not what you want them to do because they didn't do something else already and you can give them feedback without closing the window so it really comes down to a lot of user experience Allah so of crafting when it comes to going down this route there's a lot of things you can control when it comes to the user experience this was asked in the hall and I was actually going to bring it up anyway but I just want to show of hands is there anyone in here not familiar with Python okay is there anyone in this room because I'm going to make a reference to something called class inheritance at some point in this presentation who here doesn't know you don't have to understand it but who here doesn't know what class inheritance is all right I am sorry but I'm not going to be getting into the deep internals of Python and I am walking through a lot of code in this but I'm walking through it and we are going to talk about class inheritance I'm just going to make a reference to it when you see something on the slides here this subject this stuff should be pretty easy to follow along with but a working knowledge of Python probably is something that you do need alright so TK in turn GUI toolkit what exactly comes with this um if you're planning to build out some sort of interactive dialogue for end users the thing is it actually comes with a lot of options so in the upper left hand corner they're going to use a little laser pointer here because it's fun so right there those are standard entry boxes we see them in like oh Sh script pop-ups all the time Coco dialog does them just like Coco dialog on one of those entry boxes you can have it replace characters that get typed with something else like the asterisk so you have a secure text entry field option right next to that that is a combo box count and so it acts just like a drop-down option menu except you can actually have users edit the contents of it and add and remove things and then you can return that as a list next to that yet again we have radio buttons and radio buttons group together so like and you can have multiple groups on a single GUI if you really want to but it means that they have to pick from one of the available visible options in that example right there and the one below it really what it is is you select one of the radio buttons and it changes the color on the background and in that example it's just to show you that it's doing something next to that is list boxes and list boxes are also extremely flexible with because in this example it's a single selection list box but it also supports a multi selection where you pick one and then you pick everything below or above it that you want or multi selection where you actually hold down control or command and then individually pick what you want and then you can go and grab as a tuple everything that they selected next nextdoor that thing is the met is the option menu it's just a drop-down menu same thing is with my example on this the choices it's just got a color picker and it just changes the color to show you that it does something after you make a selection and then this last one right here is loading bars and loading bars is actually something I see people ask about here and there because it's mostly with cocoa dialog because cocoa dialogue does present a progress bar option for if you want someone to have feedback that something is happening in the background so there are actually two options there the indeterminate progress bar that's the style where you click on something and os10 pops up a loading bar dialog and you just see like that that's sort of a shaded white area passing over the blue you know it just does that if you load that up and start it the determine that progress bar has two different options you can load it up and start it and it'll just endlessly keep filling up that blue bar or you can actually define a value for it and you can increment that value however you want and then it will actually progress according to what you're doing in your code now all these things individually sure fine that's great it has all these options but there's not a whole lot value popping up one window that has an option menu and then there's nothing else there where a lot of the strength comes in here is when you magically merge everything together like Voltron it just gets better so this this window right here is actually just doesn't have any code changes from all the other ones it's actually just merging all the codes from all those different examples grid it out into one window and I'll explain gridding in a little bit here so the file that's in the github repo is called tech inter or TK inter widget examples you just need to run you just need to run the filing and then you'll get a whole smattering windows populating up on your screen there's a route one that says close this one when you're done it'll close all the others all right and then if you go through the example code several of them make use of something which we'll walk through a little bit later which involve some storing what you see on the screen in a variable so that you can manipulate the contents on-screen or call it out later and then the other thing that I want to call out here was that the combo boxes list boxes and option menus can all be dynamically populated you don't have to hard code that stuff you can pass things into it or have it collect data from somewhere else and then it'll populate those options when the window loads and in some cases you can actually change the contents of this option boxes and list boxes and whatever as the program is running so it actually leads to a lot of crazy little things that you can do that just pop up for the end user for them to interact with something this here is one such example of that in self-service when somebody wants a new iPhone they open it up they click on order an iPhone it pops this up then after they make all their selections of what they want it creates a ticket to order it and this is all being dynamically populated in the and the in the program when it runs it actually pulls down data from somewhere else and all those list box options you can see if the contents are actually changing as I scroll around here because we say that you get 300 bucks towards an iPhone so there's actually a JSON type on my listing that's inside there which says which bottle is OK which storage amounts are okay and which colors are okay and in our case we don't really care so all the color options are there and they just point to a URL where it goes and grabs the image that's showing so that's a that's a complicated that's a complex example because you can see it's using a lot of different features of the language and of the GUI toolkits all at once so we're going to get started here and I just need to make a quick note something in case you're already browsing the code and that's a TK answer and ttk because you might see T TK imported in there and teeka enters the base library it contains the the class it's going to be the root object you always need to use this this is how you generate or initialize the application it also has all the base widgets that we're going to be using ttk is an add-on and it actually has several versions of those widgets that are better themed for the operating system and with very few exceptions here everything is going to be just shown using the standard TK enter version of the widget but there is a one exception to that which I'll call out later all right so what we're going to do here is we're going to create a boilerplate and the boilerplate is a basic template from which we can then copy and paste it into a new project to get started so we don't have to keep redoing a bunch of stuff to get our to get our base on my window code and yes there is a bit of code with TK enter it doesn't just work right out of the box it does require some setup you know it's not quite on the same level as building an application in Xcode but there is quite there is some code to do this and we're going to actually walk through the code so you can better understand it and yeah basic template and we're going to do a walk through all right so first up is the basic and the ugly and kind of just what we want to do for the base for the base window that will build upon is to get something that looks approximate to what the standard os10 dialog looks like you know same gray background buttons look similar similarly placed you know we're going to use this as the basis for what our boiler code should generate if you were just straight up running and just to go back to the whole thing about how TK enter works across platforms like on the top and the bottom here we have Mavericks on the top elcapitan on the bottom and that's because when you can take the same TK inter code from one version of OS 10 to another and it will theme itself more closely to that version so that the way the buttons and all the other elements look like they belong on that version of the operating system all right so Bay sick and ugly and this is the number one thing that people hate about TK inter when they go try for the first time and that is that there is a white background that doesn't look like it belongs in OS 10 it looks even worse when you actually start populating stuff in there you have a big ugly white window populating it we're going to get to that in a moment though on the left here this is the basis this is as basic you can actually get way more basic than this for a TK inter application but this is a template that I sort of settled on for this in the main function we're going to be creating the root of the application that's you can see at the top there I'm importing TK interesti cave you'll see that in examples all over the web because it gets really really frustrating to type TK enter for everything that you want to use but at the same time I will call out the LC a lot of examples where they'll say from TK enter import star which means it's just imports all the classes as their own names don't do that in any of your Python code unless that is how the library is designed it makes your code really hard to read and other people don't like it so if you need a shorthand it use this method and technically that's incorrect because I'm taking a camelcase class and I'm doing it as TK if I were to throw this through pylons you know it would scream at me for doing that anyway I digress TK TK that right there that just the root application that is how you start this every single time this chunk of code right here this is that reference to class inheritance that I'm going to make just once a frame you see up there where it says app and then parentheses TK frame a frame is a type of container for TK enter so what we're actually doing is we're I'm creating a class which is a frame and we're so it's going to inherit everything that the frame does and then we're going to build stuff into it more easily so I'm not really going to get into this because you know sometimes when you're looking at examples of class inheritance you'll see a call to something called super and otherwise you'll see it's syntax like I'm using here where I'm actually calling TK frame and it's nit method and passing stuff into it just go get a quick tutorial about Python classes to just get the basics because this is really just the basics about classes right here it's not it's not really overly complicated it's when you get into other things you can do with class inheritance or multi inheritance that it gets complicated and we're not touching any of that stuff today you'll have to worry the big important pieces here is um right away I'm calling something called PAC so self self means I'm referencing the class that I'm in and I'm telling it to pack itself it's a frame it's a widget all the widgets in TK enter you have to place them in your GUI and there are three different methods for that the easiest is pack well pack does is you call pack on the widget that you just typed in and it will place it in sequential order in the GUI top to bottom now there's some other methods for tweaking that which you'll see the minute here but that's the basic that's the basic gist of it grid will explain a little bit later place I never use I'm sure that there is actually some really good use cases right but place means that you actually give it XY pixel coordinates and you tell it always goes there don't use that you'll be very sad trying to make that all work together and keep it floating in the right position in plate if you're using place you can overlap elements if you're using pack you can't overlap elements if you start mixing and matching pack and grid bad things can happen we'll cover that don't mix pack and grid or else you're going to have a bad time so then right after that you see there we're calling the master the master is our root object so as you can see down there the main function app equals and we're calling our class we're passing the root into it in TK enter every time you create a widget it has to have a parent in this case our frame our frame where all the stuff is actually contained within it that gets displayed on the screen the parents of the frame is our root application the label in there we're saying self as the first argument the first arguments always the parents or the master so in this case we're saying that label goes into belongs to the frame so that way it packs the label inside the frame and this is a shortcut here because since we're not doing anything we're just showing text on the screen it's just one line we're calling TK label telling it what we want to say and then we're just packing it right away and this code here is the basis for what you see on the right hand side there the Mavericks one only looks a little pixelated because I was doing that in a virtual machine whereas the other one I was just doing on my main desktop but you'll see that it's actually using the system fault for that version of OS 10 by default you know you don't have to do anything weird or fancy to get San Francisco to display all right so here we're going to start doing some things to start controlling the basic appearance here because the ultimate goal this is that we want to present dialogues that look like they belong to OS 10 to our users so it blends nicely so first things first here you'll see that we've got this new thing that we added into it master resizable and we're passing false false we're passing false twice because you can make this independent you could allow them to resize it on the X or Y axis independently and here we're telling it that they can't do it either so whatever the frame whatever the window ends up as for a size after we put all of our content to it it's going to stay that size and they can't resize it you can see that on the right hand side the VM the green button for maximizing the window is now grayed out well one thing I forgot to mention is that you see those three kind of do I didn't think it would be this dark when I chose this color scheme but those three dots that you're seeing throughout there this is the walkthrough part so the dots say that there was code there in front or above or behind this thing this is just all the new stuff so we're not showing any of the code from the previous slide all right so now we have on TK palette and what the palette is is on the master we're actually setting what the background color is and we're telling it it's going to be this shade of gray we matches El Capitan shade of grade and if you wanted to if you want to look just a little bit different and then more accurately match across versions of others 10 the hex the hex code for that is actually e 6 e 6 e 6 semantics whatever it's great as the important thing see it's great so what we want we want a great background this chunk of code right here is also something where you can actually have some fun if you're building GUI this way because this chunk of code right here is calculating the x and y values for where we're going to have the window draw on the display in this case what the code here is doing is it's calculating the center of the screen horizontally and one-third from the top down for the Y so it's centered but slightly elevated which to me just works better because people's eye level is usually a little bit higher than just the direct center of the screen now this is just this is just calculating that the thing is you can pass into this geometry method any coordinates you want you can draw your windows anywhere on the screen with precision that's relative to the screen size and this code can be a good starting point for that in this case though in my boilerplate I always have it drawing that window sort of upper center and then right here this is also something which is it's optional later on well this is doing right now is um TK enter of course it talks to the window manager and says I want make a GUI well when you make a GUI just by default there's going to be a blank Python menu option across the top with other screen when you have the window selected you get rid of that by passing an empty ttk enter menu widget into it you know there's that there's nothing in that widget I'm just creating a empty menu widget that the master is the parent of and then I am passing it into the config for it menu equals a blank menu so now when this GUI fires up and you click on it there's no menu bar option it doesn't say Python with no options or anything like that that is just a user experience thing because you know we're not going to have file edit view menus for this little GUI then this last thing is a bit of a hack I'm going to admit that there is an unfortunate thing about using of this method with T Kantor and that is that your gooeys do not come to the front of the window stack by default now there are actually there is actually is on a configuration change that you can make on the root inside TK enter which will bring it to the front but that won't make it active it'll just bring the window to the front but they still have to click on the window to make it the active window this here calls some quick Apple script to bring the window for the Python process all the way to the front and that makes it the active window at the same time there in addition to that you also don't have to use sub process for that if you are if you want to get into it and for it just or anyone who isn't quite aware or to another sub process is actually calling OS a script and it's telling the finder bring Python to the front you could do the same thing by importing from foundation and it's Apple script and then passing the string into NS Apple script and then calling that which is a bit more native because you're not shelling out both methods work this is one line fits better on my slides so I chose that all right so everything you get into some better stuff here so buttons we need buttons you have no limit on the number of buttons you can have on a window in TK and ER you could make a 16 by 16 grid of buttons until the user to pick one and then they don't know what will happen it's like the mystery box so this code right here these are our buttons TK button telling it the text that we want to say the text can be whatever you want I haven't tried to get but I believe emoji will work for this too if you really want to try it you'll see that on the top one the okay won't I have an extra key word for active that's what's highlighting the button blue so when the GUI comes up the okay button is the default button and it's blue that's the only difference there are lots of widgets actually support that default keyword you just have to go look through the docs of them to see what they what they do or don't support because keywords are shared across a lot of them I'll point you to the documentation for a lot of these things later the other thing that you'll notice is that I'm doing this thing with PAC where I'm saying side right so this is where you can somewhat customize how the PAC method works in this case when you call PAC by itself like I said it doesn't sequentially top-down it'll pack your widgets when you do when you ask siding there I'm packing the label from earlier in our code so that's at the top but now on the next line where it would pack the next which I'm saying side right so it actually aligns it to the right but then if the widget right after that I say side right again it packs that one on top of that going right so we actually end up with a line of them that can get messy later on if your PAC if you're trying to do a whole bunch of widgets but our next on our next slide we're actually going to cover how to organize that the other great thing here is this the command keyword and you'll see that I'm actually pointing it to these click methods because in a class you can have a class have its own functions they're called methods and there's no parentheses after that because if you add parenthesis then that means it's trying to execute the code as Python is reading through it no you're just telling you're just pointing it to your functions down there and what this does is on when they click on that button that means it goes to execute the code for the function that you're pointing to with the command keyword and you can have it do whatever you want you'll notice that on the okay well I'm just having it say print the user click OK on the cancel one which I forgot to add a box drop four you'll see self master destroy that closes the GUI so you can actually do whatever you want without closing the window until you call self master destroy until you kill off the root of the application it can stay open and you can keep doing things you don't have to have the dialogue clothes to start executing the actions that they that they wanted to perform alright so here is where we get into the organization and this is where things will start making more sense and you're going to notice something on here a little bit because a little bit ago I said don't mix and match grid and Packer else you'll have a bad time or is that a little early that's a little really I'm not using grid yet so disregard that just now so up here I'm just talking about again how long this our class the the the main container for all of our stuff is a frame well now we're actually adding in more frames where this frame is the parent so you can see what's going on here now is we have the dialogue frame but they we also have the button frame and I'm also doing some new things with pack here again where I'm actually adding padding on to it I have different padding on the y-axis that I do on the x-axis and then when I pack things inside that frame they just sort of inherit that on my extra padding around them so you can see on the right hand side there that other space around the label widget now and there's space around the buttons because the buttons are off in their own yeah they're out they're off in their own frame as well okay read that a little bit there right so the other thing about the the button frame dough is I'm telling it to anchor to the right because I have to tell that it's right justified because when I'm packing widgets in there they'll end up centering themselves even though they're aligned to the right because I've moved them from the from the main frame into a sub frame now this might seem complicated until you could make a comparison to something else who here plays with HTML who here knows what a div is does this feel kind of similar to how a div works you put divs inside divs inside divs and side divs inside other divs which are subclasses of something in bootstrap and you don't even know what your code looks like anymore but but like this is the same exact concept frames are kind of the HTML equivalent of divs you make you make a frame you put stuff in it you make a div you put stuff in and it helps organize the contents of what you see on the screen so we're actually almost done here we're just going to add a few final touches the first thing is um this is all user experience stuff and this actually also goes back to some of the strengths that we have with Teague and ER and what you see right here is this um master protocol the protocol WM window delete if you see anything in TK inter examples that has WM in it that stands for window manager which means the operating system we are overriding what the operating system will do when a user clicks that little red close button so what we're doing is we're saying if they click that little red close button call our cancel function which means that we retain control over what they're trying to do with the window they can't just close out of it without it still going through our code to have us make sure that they did what they were supposed to do and this is also where you can have a whole lot more fun because unlike with some other solutions you can bind keyboard keys to specific functions so in this in the boot and the boilerplate example by default I want to say if they hit the return key while the dialogue is open it's going to trigger my okay function so it's the same exact results as if they clicked okay they hit the escape key it'll trigger my cancel function so it's the same exact thing as if they clicked okay and you can do this with any number of keys or key combinations you can create bindings so that way you can sort of give it a more give it a better user experience because they can more natively just interact with the keyboard in the dialogue like they can with other native windows then we got this at the bottom here and I'm pretty if this took a while and I eventually found the code somewhere inside monkey's codebase so when you're firing off these uh TK Indra dialogues you'll notice that this Python rocket ship thing appears on the doc that's because the codes being executed through the Python launcher and when you open up something on the Mac that the icon for that has to appear in the doc so you get this you know funny little icon nobody understands like what is that why did that just pop up them on a dock using of the objective-c frameworks you can do this in a different one besides app kids does anyone know where else I think it's Foundation and asked bundles and foundation yes same same damn thing but in my case I call app kit what you can do is before you call root root equals tktk before you do that you can load the info.plist for the Python launcher because you're currently inside Python and you can dynamically flip the LS UI element value to true which will tell it there should be no dock icon when this application runs which means we now have an application where we have key bindings we're control we're controlling how they close the application it looks like it belongs on the OS 10 and it comes to the front and it also doesn't show stuff in the menu bar or the dock yes that was a lot of code just to gets that point but now we're going to get into the stuff that involves you actually building out really cool experiences for your end users it's example time so I built two examples for this presentation and we're going to walk through all the code in those examples and you can actually also pull those examples up in the github repo number one the one thing that everybody always wants a password prompt that actually has two fields for entering in the username and their password without having to do one dialog saying enter your username next I'll log enter your password you don't have to do that I know Coco dialog has this but you can roll your own and at the same time back to the whole thing where the dialog is this window doesn't have to close until you're ready for it to close you can also further customize this even more but as a base as a base script here we're going to go through some of the some of the things in this code which are is again this is built on top of our boiler plate so I'm only showing the changes I made in the code you know from our boiler plate this is a new kind of widget message message is a little different from a label because a message will auto wrap text by default if you see in here there's a few things that I'm doing here I'm telling it to be left-justified I got my string of text up there there's also something else that's sort of interesting here and that's so this little piece right here font there actually because you know tee Kanter is great for consistency they're actually two different ways to change font values on widgets you can actually do a whole bunch of different stuff on the screen all at the same time so like when the original max supported multiple fonts you know people went crazy with that but in this case I'm actually just passing a string in the string is just the font I want the size I want and then the style that I want and T Kandra just parses that and that's why on the previous side you saw you it was in bold and slightly bigger font the top saying please enter your user name and password to pools also work for this and you'll see an example of a tuple version of this later alright continuing on with the code I told you there was a lot of code in this presentation don't don't lose don't lose it now but we're doing something different now so in the first example where I just showed you an entry box or just any of the widgets that we were doing so far we haven't been as signings of anything we've just been putting them in the code one line here's a widget packet all on one line here we're doing something a little different we're assigning it to a class attribute and if you're a little fuzzy on the class attributes they're just variables they are tied to a class self dot the variables name so that means it's tied to that class so I'm actually assigning it on the entry box to one of those things the reason why we're doing that is because we want to be able to extract those values that they input in the entry boxes which means I am going down the rabbit hole little bit here so there's this little thing called scope in Python the thing is when you go to call another method inside a class like our click OK function if you weren't if you weren't to assign these things to a class to a class variable they were just through their own variables it has no way of actually going outside of its box to get those values you have to assign them something in the class so that you can actually just say self referencing the class and then the name of the variable that you want variable or other object that you want to interact with that's what we're doing here so we're actually making the entry box assigned to this class attribute they also notice that we don't have the pack on the same line the pack is actually on the second line and this is a gotcha when you call pack on the same line as the widget Python always returns something so when you call it on one line like that above where it's the TK entry box it returns the TK entry box if you call pac---- right after that well first it creates the entry box and then it does pack so it returns the very last thing it executes on the line pack returns none so you would end up with an empty value and you can't do anything with it so you have to call pack on a separate line if you're assigning it to something to interact with later this also is another little user experience thing focus set I'm telling this new entry box that it's going to take focus when the window loads that means that when it opens up it's going to be highlighted with the blue box and ready for them to type text into you right away and in that example from the TK widgets examples a file where it was the entry box that hid what you were typing in if that keyword right there the show keyword that does the magic and you can replace that with other ones too you can put the hash tag in there whatever example number two and that example is our file uploader I have this split across three windows here because this thing does a lot of stuff this one we're going to spend a lot more time on and I'll show you the actual application working at the end of this but this one takes tons of what we're doing with all this stuff up to now and actually combines it together and it makes use of a few new things so we're going to go through some of this code right here and here's one big thing right here the string bar now the Gotcha with TK enter in python TK enter can't just use the standard variable types because it's not really a Python library it's a toolkit that Python interfaces with it's got its own set of variable types that it uses so we're creating class attribute here file count and we're making that a string bar and we're giving it an initial value of blank then over here that label we're creating a label right next to right next to our our button except this label is not does not have any text we're actually assigning that variable to the text variable so cool thing about TK enter is the fact that you can dynamically change what's being shown on the screen by using things like variables assigned in place of text so instead of hard-coding the text you can make it point to a variable and then at any time in your code you can change the contents of that variable and it will display on the screen so you could actually give real-time message feedback to users as your code is executing after they click on something so down here there's a lot more going on here because you saw the text box and the screenshots there that's a that's a text widget and it's literally as it sounds it's a big text box for them to enter in a large comment or anything else and it actually is really really powerful and what you can do with it I just I not have not gone very far into any of that stuff because I'm I've only ever used it just we're entering in a comment that's going to go with a ticket or something like that pretty basic for appearance's because if you just draw a text widget onto the screen it's a flat white box or a flat gray box or it doesn't look right what we're actually doing here is I'm creating a frame for it and that frame actually is aa using a see that up there in the upper right there it says relief sunken the relief is a sort of about sort of an embossing attribute for a widget you know sunken right here means it looks like it's depressed into the screen a little bit you can also do rays so it looks like it's popping out you know things like that it's just a visual element because throughout OS 10 normally when you're interact interacting with a text field like that it looks like it's depressed into the screen a little bit so in order to get that appearance the frame is actually doing all that and then we're packing the text box into the frame you also noticed I've also got a few other things going on here with the colors for it and that is all just to make it look much more os10 II so it's got the right kind of blue it looked it's white background because if you remember earlier in our code we set it so that all of our widgets would have the correct grey background so we're now overriding that for this widget and then this is where you see that example I was talking about of the tuple method of updating the font I'm passing just two values because I don't want to add emphasis onto the text they type in but it's system font size 14 is what they'll get when they start typing into the text field once again you'll see focus at the bottom there so that when this window opens up for the first time the text field is where the focus is so they could start typing something right away and then we pack it all now use notes in one of those screenshots I actually had a file chooser overlaid on top of the window this is uh this is where some cool stuff can be done with TK enter and also where it can get really frustrating so there is a set of dialog classes available as separate items for TK enter and the one that we're using is TK file dialog and it's not just simply calling a file chooser they're actually six or seven different file chooser options to do because they will all do different things depending upon one you need the one that I'm calling right here Oh once again I got remember to click through my slides so the one that I'm calling right here is um ask open file names not ask open files ask open file names this particular one allows the user to multi select files from that pop-up window but it doesn't open the files it returns the paths to all those files there are circumstances where maybe you just want the path so the files they chose the other option to this is Oh ask open file name because you're restricting them to just one file name there's also ask open file and ask open files and when you choose those ones you get the file objects returned automatically so you don't have to go open them later but you do have to close them so there are a lot of options there and I'll show you how we interact without the file paths on when we get to our submit function so I'm going to take a moment here to go outside this though because I mentioned that there were a number of TK dialog options there's also TK color chooser I have no idea why we would need a user to pick a color but it's there you know the other big one is TK message box and TK message box is awesome and infuriating at the same time so you know the one thing you remember from that screenshot was that this dialog was overlaid on top of our parent window that's because if you pass to it parent instead of a master key word and you're telling it who the master is you know we could just pass we could just pass our route object to that and it would be the mastering to be assigned to it but then it would be an independent dialog box when you use this parent key word the dialog classes will actually render a sheet styles you can't do that anywhere else in TK inter and I don't understand why I can't create my own window class and have it renders a sheet on top of another window and if you are familiar with the sheet is when you click on something is sort of raus out the window from the top of your current window like with preferences or something and then it just you know sucks back up again when you're done it's a really cool visual effect but only these are dialogue dialogue classes can do it and it's not in the rest of the standard tkinter library I spent a week trying to figure that out and I eventually threw something against the wall and gave up the reason why I say that's infuriating is because the TK message box class allows you to do things like really quick yes/no prompts warning prompts info prompts question prompts you know the standard OS ten dialogues and they can render a sheet sorry on the window and you have to dismiss them before you go back to the main window it's really nice they show the applications icon in those dialogues when you call them which in our case is a rocket ship with a Python wrapped around it it's really not that elegant now if you were writing a standalone application you're going to deploy to OS 10 you've wrapped it up in PI 2 app and you gave it its own icon it would show that icon it would look great and wouldn't be a problem but that's not what the point of this session is the point is that we can run dialogues from a script without pre-loading anything so those dialogue options are really cool at the same time you get a Python with a rocket ship on them when you call them now that doesn't happen with the file with the file dialog because it's not showing anything on the screen except your file chooser so your mileage may vary if you actually want to make use of one of those the syntax is identical to this you just called class and you call the type of dialogue prompt you want and then you pass parent to it pass parent to it instead of assigning a master and then ill render is a sheet style I do recommend when we get to the end and I got the doc links that you go check out the docs for these things all right so next chunk of code there is a really really great thing that you can do which again all is all about controlling the user experience because we actually have a pop-up relay I'm about to show after this but if we have a pop-up overlay we don't want them doing anything on the main window while that's happening so just like you can have dynamic text changes and whatnot with widgets in Python you can also dynamically disable them and reenable them so this little class right here is actually doing that if you want to make a widget disable so it's grayed out in the interface you actually just call this configure method on it you say state equals either disabled or normal again consistency because you know enable doesn't make sense but normal makes sense so right up here I'm just this is just for Jesus just for me because I copy and paste this code around in some of my stuff sometimes I just make it dummy proof because sometimes I forget so with the state attribute it can only ever be normal or disabled so pretty much when I call this this little function I just tell it whether I not I want the widgets that are listed with it to be enabled or disabled or normal normal or disabled and right here in a two-pole I actually give it all the widgets I want it to operate on so you know we're disabling our buttons we're disabling the text field and as you have for this one that's why the oh and also the label we're disabling the file label as well so they all get grayed out in the background when our little pop-up widget occurs and then we just loop through them one by one we configure them so if I ever so after I disable them when I'm done with whether is I'm doing I call this method again and I say normal and then it will re-enable all those buttons that I should actually say go back here this can actually be made even much more dynamic because you could actually pull out a list or a tuple of all the widgets that belong to a parent object so what you could actually do instead instead of hard-coding the things that you want to flip on and off you can write some code where you pass a parent object to it and it reads out the list of widgets from the parent object and then loops over those and you can make this a lot more dynamic it gets a little tricky when you have nested frames and all that because you can't disable a frame you could have to disable what's inside the frame but if it's if you've got some pretty basic things there you could just pass all the individual frames that you want to disable to it and then it'll loop through all of them and then grey everything out all right so here we are and which wants this oh yeah this is my pop-up so the loading frame this draws a loading bar on the screen after they are done selecting files and they're going to upload them you can see that this code looks just like just like the main one you know and really you're going to see that if you're doing anything involving multiple windows the code is going to look basically the same across them there is another option called TK top-level which is a really great option for when you're creating another window in this case we're going to be drawing a frame on top of our original frame so we're getting back to I think what you mentioned about or who was that who was that asked about placing stuff on top of each other so there's a little trick in here that we're using for that all right so we're initially we're initializing it it's its parent is also the root TK object and we need that and I'll explain why in just minute here and this is the one the one exception that I mentioned I am using T TK in this option because the progress bar is a themed widget it's now available in standard TK enter so we are using T TK in order to draw our progress bar that's what this does this actually overlays a progress bar on top of the screen after they click OK in this case I'm actually doing determinants and I'm using the method where I control the progress of the progress bar as I'm executing actions in this case and look the length is in pixels by the way when I say length 250 that's in pixels so right here on that object progress I'm setting the initial value to zero which might be redundant it might already be zero by default there but I'm also setting the maximum equal to a variable called count and in the main code what I'm doing here is I'm not taking after they choose all their files we that's all gathered up as a tuple assigned to a class attribute when this gets called we're going to see in the next slide I'm actually taking the length of that tuple and passing it over so the maximum value for our progress bar is going to be equal to the number of files that we're processing and here is where the magic happens and nope I forgot something so how exactly am i overlaying a frame on top of another frame well a little bit higher up in there and I was missing a box on that one too shame on me you can see self grid grid so I actually skipped over the string of the password prompt example my bad earlier I had said don't mix pack and grid or else you're going to have a bad time that's if you're mixing pack and grid within the same container you can actually mix and match them to great effect if you are packing frames or gridding frames and then packing widgets inside them or you're packing a frame and you're gridding widgets inside the frame because when it gets down to placement the frames are individuals you know they don't share place the internal placement of their widgets with other widgets they're self-contained so you can have one frame on the screen like say you had a box of four frames on your screen it's like you're gonna put widgets in this one which it's in this one so on so forth you can grid out widgets in the first one in the first frame because you want them to be specifically placed but then you can pack widgets into the next one because you don't really care about you just want them sequentially listed top down and you don't need to grid all that crap you just pack them because they'll go top down in our password prompt I was actually gritting out the labels for username and password and the two entry boxes so that frame was packed on top of our button frame and below the message widget but inside that frame it was actually the first label was grid 0 0 the second label was grid 0 1 the first entry box was 1 1 in the second entry box or 0 1 in the second entry boxes 1 1 you know shame makes it really easy when it comes to sitting down designing your gooeys at first because you can literally just draw a basic thing on sheet of paper and you could be like well I'm going to pack them all so I've got you know kind of like bootstrap you know you're gonna pack it all so you got frame frame frame all in a row but then you can start drawing lines on the inside being like and this is how I'm going to grid out this one it makes and then you just do zero indexing starting at zero and onwards it makes it really easy to plot out how you're going to Ray you're lit your widgets and then you just pack them and grid them all right so now we're going to continue on to the submit function because I did forget about that so this is how you pull out whatever it is that they put into there cut into the text field and earlier I had mentioned how the comment the the text widget was actually really powerful well when you're pulling stuff out of it you're actually doing so by telling it you want to pull text you want to pull out the contents of the text widgets starting at this character spot and then you specify where you want to end so first character spot all the way to and end is just a shortcut word for the very last character in that so you don't have to know what it is you can do crazy things with this because there are some really cool advanced examples out there of tkinter really simple to kinter applications which are actually pretty basic text editors because you can actually a pull out stuff according to text selections and you just grab you just grab the cursor on positions and then you calculate out how many characters it is that you're pulling chunks of code out and there's a lot that you can really do with this widget and I'm just using it for the absolute most basic thing there is which is I'm just grabbing all the text oh there we go so right here if comment our strip our strip is just to remove some extraneous return characters they're always at the end of this thing it's kind of annoying just to return characters at the end of it every time you just grab everything so our strip just peels those out so I'm just checking to see if there's anything in the comment field and then if there is going to do something with it this example I'm just printing it because you can see on the command line if you're running this example if I was doing something like say submitting a form or submitting a ticket or adding a comment to a file that was being uploaded I could assign this text to another variable and then pass that on to whatever else I was doing for the logic now if we get a little further down this is where we start getting into that file list because they did choose files they selected however many files and then they hit ok so if they selected any files because there's an go back a little bit you see if selected files if a tuple is empty it returns as false so in here this is where the magic starts happening so we are calling the loading frame right there and that's all there is to it and I'm assigning it to a variable because I need to be able to kill it after I'm done with it we don't want the frame to just stay on the screen we want to get rid of it when we're done so I'm creating it I'm passing in the passing in the mat the master for our application as its parent I'm also passing in that length count of the selected file so that way that's going to set what the maximum for our progress bar is going to be then right at right under that yes then I'm calling that on state toggle function because I'm disabling everything in the background you can't interact with it any more while the loading bar is on the screen now we move on and this is where we're doing the stuff with the file paths now the shortcut to this could have just been I opened up all the files because then I would avoid a race condition because I might have grabbed the paths and then if and then between the time where they click to choose files they hit OK something could have potentially happened to those files it's possible but in this case I'm not taking all the file paths and see right there loading progress plus equals 1 I'm actually incrementing the loading bar by one as I go to process the first file then I'm calling update because sometimes you run into something where um with certain widgets they don't just dynamically render themselves when you make a change so you call update on that widget and then it will actually i'ma render with the changes and in this case we're all telling the parent window the update then right after that I'm printing out what file it is like file one of however many just on the command line could be also put into a logging function and then after that I have an artificial sleep counter in there because if we didn't have any because we're not actually doing any uploads right now it's just an example this would complete immediately if you clicked okay because it's just running through a bunch of file file paths so there's a sleep timer in there just to give us a padding and then with open the path because we're doing for path in our selected files it's just going to open up that file it's going to print out the file object just to prove that it actually is opening up a file you selected and then it'll continue the loop to the next one in which it will increment the progress bar by one you'll see the progress bar for regress you'll perform the actions on the file and continue on until it's actually done exhausting all the Selective files then at the very end when that's all done we destroy the frame that have the loading bar and like the same exact thing on our root window you know our cancel button calls master dot destroy if you want to destroy any widget that's on your screen you just call the destroy method on it so you can also dynamically take away widgets too like we're doing here and then we call our toggle function again we say normal so everything goes back to normal and then we get a little movie that show us how this whole thing works hello Mac Edmonds see that sheet style rendering right there that you can only do with the dialogues and really ticks me off you click OK the whole background gets grayed out and you see the loading bar as a progress is through each one of those files and yet remember there's a two-second sleep timer in there to artificially drag this out and then when it's done it goes right back to normal I could have added something in there also to clear out the variables and clear out the text box and all that I just sort of left it there so if you are interested in or these are the resources that I have relied upon right at the top there the docs read the docs I'm pretty sure I haven't seen a single Python related presentation where at some point they didn't tell the audience to go read the docs but this is where the TK interlibrary Doc's are for Python and I pointed you the version to ones because until Apple loads Python 3 on two of their systems we shouldn't care about three so Stack Overflow this link right here is just for the TK inter tag now remember TK enter as multi platform and multi-language which means Sikandar gets used in Ruby it gets used in Perl God would forgive you if you use pearl but you know it gets used everywhere so you know just going to that tag means you might get a lot of references to a lot of different languages but it's a universal toolkit so even if you can't find the answer specific to Python you might actually find something similar for Ruby or Perl or whatever and that or just the basic teak or tcl/tk syntax because you can build these gooeys using just the toolkit with no other program F Mott don't understand why it's called F bot but these are the old Doc's but there's still a lot of good stuff in there underneath them our TK Doc's and those are the new Doc's so I'm both of those excellent resources and that's all I've got for you thank you for coming and listening to me draw LAN about code for about an hour and if you really want to I can try to pretend to answer your questions all right we're going to try this secure your drinks yes just real quick you mentioned the dropdowns have the the custom Python icon can you like package or build in an icon and point to it is it is it possible or neither because I we push out push out icon so it's already on my system so I could point to it you could try replacing the default icon bundle in the Python launcher if you're really going to go down that route you might as well deploy your own copy of the launcher and leave the system one alone be my recommendation of course then we're getting into the realm of you know the pre deploying things are the scripts but there's a even if you are pre deploying some things there's still a lot of power in here for about being able to dynamically generate stuff anyone else there's no way I was that thorough there we go Brad wants to troll me a little bit so let's let him troll me no I don't have anything to troll you on so if I were to add another frame so I have screen number one will ask a series of questions screen number two asks a series of questions screen number three how would I structure screen two in screen three with the idea of I have this class I have this frame how could I move between those well I'm batting over two right now because once again I didn't really answer the point that he brought up how was i overlaying that widget I'm gritting it so the UH in this example of you guys go look at the code for the file uploader you'll see that the root frame the app frame it's not being packed it's actually being gridded at zero zero and then when I'm packing this frame this one size much smaller and I'm disabling everything in the background but I'm grading that at zero zero as well so it's centering it onto the existing grid of the route what you can do is you can create a switcher there are two ways to do this you can create a switcher where you're just redrawing a frame of the exact same size on top of the other one because there is a method on widgets and frames called rays so if you call rays it brings it to the forefront on the window manager so that is one option the other one is that insight et-gay there is notebook it's called notebook there is a not there's a there's an extra option in a ttk for creating tabbed views which I didn't get into because I've never used before and I was already way behind and writing all this code but there are all there are there are options for it there's a there's this guy who has a youtube series um for various programming subjects in Python and one of them he goes through how to do frame switching in T Kantor he doesn't go through the law of the process of properly organizing the stuff because he's just showing how to get the buttons to actually raise and lower the frame so that you're interacting with the correct set of widgets but either it is good it is a good example that you can build upon thank you we got 10 minutes for Q&A you guys we can wrap up now but I'm willing to answer more questions this is actually a little ridiculous and kind of based on my environment having some old stuff what's the what's the minimum OS target for this it's a good question because um I think I know it you can at least go all the way back to 10 7 and I believe you can go further than that the versions of the toolkits will be a little bit different as time has gone on right now I believe on El Cap it's odd Teek tcl/tk 8.5 of course python is also incremented in version along with that the core syntax is mote is pretty much the same across all of them though it's just that you might be missing some bug fixes here and there or possibly a widget you might not happen you may not have ttk on much earlier versions I haven't tried that though in my environment I'm usually either at the current version of Austin or the version immediately behind it so I actually don't even think about Mavericks anymore and and for the most part I'm in a similar situation I just have enough machines that yeah there are a couple of those so for anybody who is in the same position as I am who has to deal with old stuff I'm pretty sure like Pasha if you have to throw up dialogues and older versions but this is a lot more this is a lot more elegant for anything that's new so thank you very much sure there we go throw that alright are you familiar with platypus I am okay so you've got these scripts and they're raw Python scripts and you quickly glanced over an application to turn it into an application hi hi to app is what I use and it's just a wrapper it is not a wrapper okay all that we're going to go exploring here if you want some basic instructions on how to use PI to app you can go check out hip status because at the bottom of the page here I have all of my instructions on Oh for love of God all that where is the screen there we go no no full screen it Wow there we go there we go so this goes through all my instructions on how you take the source code for hip status and run it through PI to app so you can use this as a basic starting point if you're interested in actually compiling Python code into a native OS 10 application bundle and sign it there are signing instructions in there so to follow up to you you're you're basically running this inside the users account correct whatever with it so if you are if you're using monkey or the JSS and you have it execute a script on the system that script runs its route but but gooey there any limitations with that it turns you don't get any errors back from your Python haven't yet well unless there's a syntax error in my Python okay which that always happens well so with like platypus you you have limitations with sudo because of apple's security frameworks so you can run things locally but not I've known about platypus I just have never used it this process right here will actually either use the system Python or compile into it its own copy of Python and create an OS 10 bundle it's a lot like what Dropbox does because Dropbox is a Python application I'll follow up on that a little bit I think what you're getting at is if it the master process is spawned by root and it's in a user's GUI you do have to do a lot of special things well if the user starts it in self-service there's no problem because the system can follow the security sockets from self-service to the script back to the user that's not a problem but if you wanted to just pop up on the user you have to do some special magic I give somebody I need to give somebody credit and I can't think of her name wrote a brilliant article on this and I can share it with you I wish I could credit that person I just cute yeah I was I was misunderstanding what you're asking there yeah in my case all my gooey stuff is executed from self-service so the monitoring process triggers the policy which runs the script as route so I can do pretty much whatever I want from the GUI at that point it breaks it up I'll troll you for a second if Liam so if if you know all the stuff and you work for jams like he jammed paying customers have like a better Jam helper to do all this stuff you understand they're going to be watching this and I'm going to get a glare when I come back down actually I'm not there was not enough time but for hackathon project I was thinking about building sort of a Python version of that of this dynamically generate gooeys that you could make extensible I found out though and you guys need to check it out I'm going to call them out my key frog war is over there building something similar to that where you can actually take a nib file from Xcode pass it into a Python script and have it build out a GUI for you so that I'm going to be looking forward to checking that out because it's actually a library so you can either execute the library or import it into a script that'll be really cool to see but know like you can do a lot of stuff you know with ahmadies and it's like packing gridding they're actually really easy concepts so there it would be it wouldn't be a whole lot of work to get started on making some sort of you know tool where you pass some arguments or you passes a configuration and it just pops up a GUI of what you asked for now you had to bring up Jeff helper alright I think yup he's good now he really wants to throw that box and we've got four minutes do we have one more to fill up those four minutes all right is there another GUI are there other GUI not give the right word classes whatever and Python besides tkinter that you played with third party you want them and they're all right there's actually a good selection of them good yeah the third party libraries but yes there are other options if you want to go down the Python route of building Python GUI applications you don't have to use CKD enter if you don't have to rely upon nit standard library in my example everything was standard library there was nothing you had the preload you didn't have to use pip to install packages or anything this was entirely standard library which goes the theme of you can deploy a GUI without having to do any sort of pre deployment of things like gogo dialog if you want go down the rabbit hole and the other way you could extend TK enter like crazy with add-on packages like pillow so that you can dumb up ya pillow so that you can actually then I'll import a ma non jiff images into it because the sarig library only sports gifs so when you were seeing that iPhone application up on the screen it was downloading gifs that I'd already pre converted because that's what supports out-of-the-box but there are add-on libraries which adds support for the whole gamut of file types for rendering within the application so if you want to go to that if you want to go a third-party library route and with what you're building and you want stick with Python sky's the limit pretty much like with anything else with Python there's a library for it if we got no more thanks
Info
Channel: MacAdmins Conference
Views: 153,147
Rating: undefined out of 5
Keywords:
Id: Wb1YFgHqUZ8
Channel Id: undefined
Length: 73min 0sec (4380 seconds)
Published: Wed Jul 20 2016
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.