FLOSS Project Planets

Reuven Lerner: Save time — and 30% — with my 25 Python, Git, and data science courses!

Planet Python - Fri, 2021-11-26 06:57

It’s that time of year — Black Friday, when everything goes on sale. At my online store, with more than 25 courses about Python, data science, Git, and regular expressions, I’m giving 30% off of the usual price.

Here’s what some students have said about my courses:

  • “This is by far the most amazing Python course I have taken. It is full of advanced information, especially for people who want to take their Python skills to next level.” — Punit Jain
  • “I think you have an exceedingly rare crystal clear explanation of all things Python and I look forward to more content!” — David Punsalan
  • “Reuven’s teaching approach is excellent in terms of pacing and cadence. I never felt that too much was being covered at one time or that a topic was covered too fast before moving onto to the next item.” — Jason Wattier

Every single one of my courses also includes exercises — not only questions and answers, but a walk-through of the solution, live-coding into Jupyter notebooks.

No matter how long you’ve been using Python, one of my courses will help you to write better, clearer, more idiomatic, more efficient code. And you’ll do it in less time, freeing you to do other things, such as spend time with family, or relax with friends.

Here’s what you can find in my online store, at https://store.lerner.co.il/:

And yes, in case you’re wondering: I’ve added a bunch of courses in the last year, including intro courses about Python files and modules, and advanced courses (recordings of Webinars) about functional Python, packages, threading, and asyncio.

Just use the coupon code BF2021 at checkout to get 30% off. It’s a bit hard to see where you can enter the coupon code, so I’ve included it in the above links.

Wondering what course(s) are best for you? E-mail me at reuven@lerner.co.il, or DM me on Twitter at @reuvenmlerner.

The post Save time — and 30% — with my 25 Python, Git, and data science courses! appeared first on Reuven Lerner.

Categories: FLOSS Project Planets

How To Make Plasma Panel Fit Content (Like A Dock)!

Planet KDE - Fri, 2021-11-26 05:45
💸💸 Help me contribute to KDE and do these videos: 💸💸 Patreon: https://www.patreon.com/niccolove Youtube: https://www.youtube.com/channel/UCONH73CdRXUjlh3-DdLGCPw/join Paypal: https://paypal.me/niccolove Stay in the loop: https://t.me/veggeroblog My website is https://niccolo.venerandi.com and if you want to contact me, my telegram handle is [at] veggero.
Categories: FLOSS Project Planets

Python GUIs: Create multiple windows in PySide6 — Opening new windows for your application (updated for PySide6)

Planet Python - Fri, 2021-11-26 04:00

In an earlier tutorial we've already covered how to open dialog windows. These are special windows which (by default) grab the focus of the user, and run their own event loop, effectively blocking the execution of the rest of your app.

However, quite often you will want to open a second window in an application, without interrupting the main window -- for example, to show the output of some long-running process, or display graphs or other visualizations. Alternatively, you may want to create an application that allows you to work on multiple documents at once, in their own windows.

It's relatively straightforward to open new windows but there are a few things to keep in mind to make sure they work well. In this tutorial we'll step through how to create a new window, and how to show and hide external windows on demand.

Creating a new window

In Qt any widget without a parent is a window. This means, to show a new window you just need to create a new instance of a widget. This can be any widget type (technically any subclass of QWidget) including another QMainWindow if you prefer.

There is no restriction on the number of QMainWindow instances you can have. If you need toolbars or menus on your second window you will have to use a QMainWindow to achieve this. This can get confusing for users however, so make sure it's necessary.

As with your main window, creating a window is not sufficient, you must also show it.

python from PySide6.QtWidgets import QApplication, QMainWindow, QPushButton, QLabel, QVBoxLayout, QWidget import sys class AnotherWindow(QWidget): """ This "window" is a QWidget. If it has no parent, it will appear as a free-floating window as we want. """ def __init__(self): super().__init__() layout = QVBoxLayout() self.label = QLabel("Another Window") layout.addWidget(self.label) self.setLayout(layout) class MainWindow(QMainWindow): def __init__(self): super().__init__() self.button = QPushButton("Push for Window") self.button.clicked.connect(self.show_new_window) self.setCentralWidget(self.button) def show_new_window(self, checked): w = AnotherWindow() w.show() app = QApplication(sys.argv) w = MainWindow() w.show() app.exec_()

A main window with a button to launch a child window,

If you run this, you'll see the main window. Clicking the button may show the second window, but if you see it it will only be visible for a fraction of a second. What's happening?

python def show_new_window(self, checked): w = AnotherWindow() w.show()

Inside this method, we are creating our window (widget) object, storing it in the variable w and showing it. However, once we leave the method we no longer have a reference to the w variable (it is a local variable) and so it will be cleaned up – and the window destroyed. To fix this we need to keep a reference to the window somewhere, for example on the self object.

python def show_new_window(self, checked): self.w = AnotherWindow() self.w.show()

Now, when you click the button to show the new window, it will persist.

However, what happens if you click the button again? The window will be re-created! This new window will replace the old in the self.w variable, and – because there is now no reference to it – the previous window will be destroyed.

You can see this in action if you change the window definition to show a random number in the label each time it is created.

python from random import randint class AnotherWindow(QWidget): """ This "window" is a QWidget. If it has no parent, it will appear as a free-floating window as we want. """ def __init__(self): super().__init__() layout = QVBoxLayout() self.label = QLabel("Another Window % d" % randint(0,100)) layout.addWidget(self.label) self.setLayout(layout)

The __init__ block is only run when creating the window. If you keep clicking the button the number will change, showing that the window is being re-created.

One solution is to simply check whether the window has already being created before creating it. The example below shows this in action.

python from PySide6.QtWidgets import QApplication, QMainWindow, QPushButton, QLabel, QVBoxLayout, QWidget import sys from random import randint class AnotherWindow(QWidget): """ This "window" is a QWidget. If it has no parent, it will appear as a free-floating window as we want. """ def __init__(self): super().__init__() layout = QVBoxLayout() self.label = QLabel("Another Window % d" % randint(0,100)) layout.addWidget(self.label) self.setLayout(layout) class MainWindow(QMainWindow): def __init__(self): super().__init__() self.w = None # No external window yet. self.button = QPushButton("Push for Window") self.button.clicked.connect(self.show_new_window) self.setCentralWidget(self.button) def show_new_window(self, checked): if self.w is None: self.w = AnotherWindow() self.w.show() app = QApplication(sys.argv) w = MainWindow() w.show() app.exec_()

Child window with a label randomly generated on creation.

Using the button you can pop up the window, and use the window controls to close it. If you click the button again, the same window will re-appear.

This approach is fine for windows that you create temporarily – for example if you want to pop up a window to show a particular plot, or log output. However, for many applications you have a number of standard windows that you want to be able to show/hide them on demand.

In the next part we'll look at how to work with these types of windows.

Toggling a window

Often you'll want to toggle the display of a window using an action on a toolbar or in a menu. As we previously saw, if no reference to a window is kept, it will be discarded (and closed). We can use this behaviour to close a window, replacing the show_new_window method from the previous example with –

python def show_new_window(self, checked): if self.w is None: self.w = AnotherWindow() self.w.show() else: self.w = None # Discard reference, close window.

By setting self.w to None the reference to the window will be lost, and the window will close.

If we set it to any other value that None the window will still close, but the if self.w is None test will not pass the next time we click the button and so we will not be able to recreate a window.

This will only work if you have not kept a reference to this window somewhere else. To make sure the window closes regardless, you may want to explicitly call .close() on it. The full example is shown below.

python from PySide6.QtWidgets import QApplication, QMainWindow, QPushButton, QLabel, QVBoxLayout, QWidget import sys from random import randint class AnotherWindow(QWidget): """ This "window" is a QWidget. If it has no parent, it will appear as a free-floating window as we want. """ def __init__(self): super().__init__() layout = QVBoxLayout() self.label = QLabel("Another Window % d" % randint(0,100)) layout.addWidget(self.label) self.setLayout(layout) class MainWindow(QMainWindow): def __init__(self): super().__init__() self.w = None # No external window yet. self.button = QPushButton("Push for Window") self.button.clicked.connect(self.show_new_window) self.setCentralWidget(self.button) def show_new_window(self, checked): if self.w is None: self.w = AnotherWindow() self.w.show() else: self.w.close() # Close window. self.w = None # Discard reference. app = QApplication(sys.argv) w = MainWindow() w.show() app.exec_() Persistent windows

So far we've looked at how to create new windows on demand. However, sometimes you have a number of standard application windows. In this case rather than create the windows when you want to show them, it can often make more sense to create them at start-up, then use .show() to display them when needed.

In the following example we create our external window in the __init__ block for the main window, and then our show_new_window method simply calls self.w.show() to display it.

python from PySide6.QtWidgets import QApplication, QMainWindow, QPushButton, QLabel, QVBoxLayout, QWidget import sys from random import randint class AnotherWindow(QWidget): """ This "window" is a QWidget. If it has no parent, it will appear as a free-floating window as we want. """ def __init__(self): super().__init__() layout = QVBoxLayout() self.label = QLabel("Another Window % d" % randint(0,100)) layout.addWidget(self.label) self.setLayout(layout) class MainWindow(QMainWindow): def __init__(self): super().__init__() self.w = AnotherWindow() self.button = QPushButton("Push for Window") self.button.clicked.connect(self.show_new_window) self.setCentralWidget(self.button) def show_new_window(self, checked): self.w.show() app = QApplication(sys.argv) w = MainWindow() w.show() app.exec_()

If you run this, clicking on the button will show the window as before. However, note that the window is only created once and calling .show() on an already visible window has no effect.

Showing & hiding persistent windows

Once you have created a persistent window you can show and hide it without recreating it. Once hidden the window still exists, but will not be visible and accept mouse/other input. However you can continue to call methods on the window and update it's state -- including changing it's appearance. Once re-shown any changes will be visible.

Below we update our main window to create a toggle_window method which checks, using .isVisible() to see if the window is currently visible. If it is not, it is shown using .show() , if it is already visible we hide it with .hide().

python class MainWindow(QMainWindow): def __init__(self): super().__init__() self.w = AnotherWindow() self.button = QPushButton("Push for Window") self.button.clicked.connect(self.toggle_window) self.setCentralWidget(self.button) def toggle_window(self, checked): if self.w.isVisible(): self.w.hide() else: self.w.show()

The complete working example of this persistent window and toggling the show/hide state is shown below.

python from PySide6.QtWidgets import QApplication, QMainWindow, QPushButton, QLabel, QVBoxLayout, QWidget import sys from random import randint class AnotherWindow(QWidget): """ This "window" is a QWidget. If it has no parent, it will appear as a free-floating window as we want. """ def __init__(self): super().__init__() layout = QVBoxLayout() self.label = QLabel("Another Window % d" % randint(0,100)) layout.addWidget(self.label) self.setLayout(layout) class MainWindow(QMainWindow): def __init__(self): super().__init__() self.w = AnotherWindow() self.button = QPushButton("Push for Window") self.button.clicked.connect(self.toggle_window) self.setCentralWidget(self.button) def toggle_window(self, checked): if self.w.isVisible(): self.w.hide() else: self.w.show() app = QApplication(sys.argv) w = MainWindow() w.show() app.exec_()

Note that, again, the window is only created once -- the window's __init__ block is not re-run (so the number in the label does not change) each time the window is re-shown.

Multiple windows

You can use the same principle for creating multiple windows -- as long as you keep a reference to the window, things will work as expected. The simplest approach is to create a separate method to toggle the display of each of the windows.

python import sys from random import randint from PySide6.QtWidgets import ( QApplication, QLabel, QMainWindow, QPushButton, QVBoxLayout, QWidget, ) class AnotherWindow(QWidget): """ This "window" is a QWidget. If it has no parent, it will appear as a free-floating window. """ def __init__(self): super().__init__() layout = QVBoxLayout() self.label = QLabel("Another Window % d" % randint(0, 100)) layout.addWidget(self.label) self.setLayout(layout) class MainWindow(QMainWindow): def __init__(self): super().__init__() self.window1 = AnotherWindow() self.window2 = AnotherWindow() l = QVBoxLayout() button1 = QPushButton("Push for Window 1") button1.clicked.connect(self.toggle_window1) l.addWidget(button1) button2 = QPushButton("Push for Window 2") button2.clicked.connect(self.toggle_window2) l.addWidget(button2) w = QWidget() w.setLayout(l) self.setCentralWidget(w) def toggle_window1(self, checked): if self.window1.isVisible(): self.window1.hide() else: self.window1.show() def toggle_window2(self, checked): if self.window2.isVisible(): self.window2.hide() else: self.window2.show() app = QApplication(sys.argv) w = MainWindow() w.show() app.exec_()

A mainwindow with two child windows.

However, you can also create a generic method which handles toggling for all windows -- see transmitting extra data with Qt signals for a detailed explanation of how this works. The example below shows that in action, using a lambda function to intercept the signal from each button and pass through the appropriate window. We can also discard the checked value since we aren't using it.

python import sys from random import randint from PySide6.QtWidgets import ( QApplication, QLabel, QMainWindow, QPushButton, QVBoxLayout, QWidget, ) class AnotherWindow(QWidget): """ This "window" is a QWidget. If it has no parent, it will appear as a free-floating window. """ def __init__(self): super().__init__() layout = QVBoxLayout() self.label = QLabel("Another Window % d" % randint(0, 100)) layout.addWidget(self.label) self.setLayout(layout) class MainWindow(QMainWindow): def __init__(self): super().__init__() self.window1 = AnotherWindow() self.window2 = AnotherWindow() l = QVBoxLayout() button1 = QPushButton("Push for Window 1") button1.clicked.connect( lambda checked: self.toggle_window(self.window1) ) l.addWidget(button1) button2 = QPushButton("Push for Window 2") button2.clicked.connect( lambda checked: self.toggle_window(self.window2) ) l.addWidget(button2) w = QWidget() w.setLayout(l) self.setCentralWidget(w) def toggle_window(self, window): if window.isVisible(): window.hide() else: window.show() app = QApplication(sys.argv) w = MainWindow() w.show() app.exec_()

For an in-depth guide to building Python GUIs with PySide6 see my book, Create GUI Applications with Python & Qt6.

Categories: FLOSS Project Planets

PreviousNext: Sponsoring Drupal Contribution

Planet Drupal - Thu, 2021-11-25 23:18

As an open-source project, Drupal relies on the sustained contributions of individuals and organisations to keep it well maintained, develop, and grow to stay relevant in a competitive landscape.

The project founder, Dries Buytaert has highlighted the problems many open source projects have of balancing the makers and takers. Increasingly, organisations that have traditionally contributed to Drupal have had challenges keeping the level of contribution going, and have had to look to new ways to support the project.

Sponsoring Drupal contribution is a new and exciting way for PreviousNext to give back to the project as well as the community.

by kim.pepper / 26 November 2021

PreviousNext has a long history of contributing to Drupal. For the last 12 years our contributions have ranged from speaking at global and local Drupal events, to being a part of the team that ran the first DrupalCon in Sydney, Australia. Our team consists of core committers, sub-system maintainers, module maintainers, and security team members, as well as members of the DrupalSouth board and committees. We have consistently ranked in the top ten contributors globally.

Recently we have achieved the only Platinum Drupal Certified Partner status in Australia, and are committed to maintaining it.

Since our inception, we have contributed back via the projects we develop as well as a policy of 20% time for contribution, and we will continue to do this going forward. We believe this benefits everyone. Our employees are receiving code reviews from some of the brightest minds in the Drupal world, increasing their expertise - a form of training if you like. PreviousNext is also able to raise its profile based on these contributions, and market its expertise to future customers.

Despite this, we see a big opportunity in sponsoring specific individuals who can have a big impact on the project.

V Spagnolo (@quietone) is a key member of the Australia & New Zealand Drupal community. She has long been a maintainer of the Migrate core sub-system, a central contributor to the Bug Smash Initiative, and her contributions earned her winner of the Open Source Contributor award at the New Zealand Open Source Awards in 2018. She has recently been appointed a Provisional Release Manager for Drupal.

In short, she provides highly valuable contributions to both the project and the regional community.

Today, we are proud to announce that we will be financially sponsoring part of quietone's contribution time going forward, as another way for PreviousNext to help progress the project.

Tagged Core contribution, Contributing
Categories: FLOSS Project Planets

Reproducible Builds (diffoscope): diffoscope 194 released

Planet Debian - Thu, 2021-11-25 19:00

The diffoscope maintainers are pleased to announce the release of diffoscope version 194. This version includes the following changes:

[ Chris Lamb ] * Don't traceback when comparing nested directories with non-directories. (Closes: reproducible-builds/diffoscope#288)

You find out more by visiting the project homepage.

Categories: FLOSS Project Planets

Evolving Web: My First 3 Months at Evolving Web

Planet Drupal - Thu, 2021-11-25 13:48

Last August, I joined Evolving Web as a Content Writer & Editor. Three months later, I have to say this has been a fantastic journey! I'm super proud of being part of an incredible marketing team and a true digital powerhouse. Here I'll share a few impressions of Evolving Web and how its collaborative culture and welcoming environment have already taught me some lessons and enabled me to develop my skills.

From Journalism to Content Marketing (and Beyond)

I was a journalist for more than 20 years before moving to content marketing in 2018. I've specialized in writing and editing blog posts, newsletters, website copy, and other types of content about topics ranging from machine learning and digital transformation to online consumer behaviour.

When I got a job offer from Evolving Web, I thought I was fully equipped for the job right from the start, thanks to my experience, writing and editing skills, and business-oriented mindset. I thought that was all I needed to create the best content marketing a web agency could have.

It turns out I was wrong. Sure, my background has been a great help from day one—like when I write case studies about our clients' projects and interview my colleagues about their experiences. However, creating Drupal-related content can be challenging for a non-developer like myself. Writing about the platform's technical aspects demands a certain knowledge that you can only acquire with dedication and time.

So, with every new assignment, I end up learning valuable things about Drupal. At the same time, I try to block time off my schedule to do some reading and learn more about Drupal on my own.

This kind of challenge excites me. I'm curious by nature, and learning new things is something everyone should be open to, no matter how experienced they may be. Nothing could have prepared me for the world of possibilities Drupal presents, and learning and creating content about it has only made me a better writer and editor.

I have to give credit to my generous, talented colleagues, who have been immensely supportive throughout my journey. They're always willing to share their knowledge and even write about their experiences on our blog. Along with our tight-knit structure, this collaborative spirit emphasizes one of Evolving Web's biggest strengths: a sense of belonging. I feel like I'm part of something and that my work makes a difference, whether it's to our readers via our blog or helping the company itself expand its reach. This is much better than just feeling like a cog in the wheel, as too often happens in some larger companies.

The Importance of Belonging

In the end, everyone wants to feel like they belong. At Evolving Web, my first taste of that was during my first week on the job at our summer picnic. I literally knew nobody there, but they all made me feel welcome right away. We had a fantastic time, enjoying some great weather in the heart of Old Montreal (with social distancing, of course). Right then, I could tell that Evolving Web and I were a great match.

Then, after a couple of weeks on the job (and after two COVID jabs), I felt more comfortable going into the office regularly. While we're free to work from home, I personally prefer to go to the office, and by doing that, I rediscovered the power of collaboration. After more than a year of social distancing, I could again experience how working close to one another makes our output richer. In my case, speaking in person to developers, designers and project managers speeds up and improves my writing and editing process.

Coming to the office also opened my eyes to how Evolving Web's environment is as chill as results-driven. People are always willing to put their heads together and support each other, but come lunchtime, we all go into the kitchen to relax, laugh, and play some mean foosball. (I'm still terrible at it, but my game is slowly improving. Baby steps!)

Take a look at what it's like to work at Evolving Web

The Power of Diversity

Finally, I want to say a few things about diversity. As a Brazilian who's lived in Montreal for two years, I took a job at Evolving Web hoping this would be a workplace that genuinely valued plurality. Three months later, I can see how solidly diverse we are as a team. We all come from—or even live in—many different places, including Ukraine, Turkey, France, Brazil, Costa Rica, Lebanon, China, Vietnam, and Québec and Ontario.

This plurality enables me to express myself freely, knowing that my colleagues will value my input and work as much as anyone else's, regardless of where I come from or my cultural background. It might not sound like much, but this has been a first for me since I came to Canada. This culture of diversity is crucial for me to perform my best.

Here's How Drupal Can Be a Force for Diversity and Inclusion

The past three months on the job have been full of learning, hard work, fun, and collaboration. It's been one of the most enriching experiences in my career, and I'm sure Evolving Web and I are set to achieve great things together. I'm looking forward to the next three months! (And the following three months, and the next, and the next...)

I encourage you to take a look at our job opportunities! Join our team :)

+ more awesome articles by Evolving Web
Categories: FLOSS Project Planets

Chocolate Lily: Multiple version compatibility in Drupal--managing the tradeoffs

Planet Drupal - Thu, 2021-11-25 12:57

If you're a seasoned Drupal module developer, or even a relatively new one, it's hard not to like the fact that, starting with Drupal 8.7.7, it's possible for a single version of a module to be compatible with multiple versions of Drupal core. Suddenly, maintaining your module became way easier. It's noteworthy enough that the process of making a module work with the Drupal 9 release was incomparably easier than any previous major version upgrade. But beyond that, you could actually maintain a single version for both Drupal 8 and 9, or both Drupal 9 and 10. How great is that?

But - and there always is a but, isn't there? - it's not quite so straightforward. There are some significant tradeoffs to sticking with a single release branch for two major versions of core. I'll look at a couple here - deferred refactoring and missed improvements - and ways to mitigate them.

Categories: FLOSS Project Planets

Matt Glaman: Better static analysis with entity type storages in phpstan-drupal 1.10

Planet Drupal - Thu, 2021-11-25 11:53

I am happy to announce the 1.1.0 release of phpstan-drupal! This is a minor version bump due to a breaking change in the configuration options for phpstan-drupal. Before we dive in, I want to give major thanks to brambaud for their outstanding contributions this month. Their work has brought excitement to the table for untangling Drupal's magical bits for static analysis. I also want to thank eiriksm for his work to fix some of Drupal's magic when fetching field value properties.

Here is a summary of the significant improvements:

Categories: FLOSS Project Planets

ItsMyCode: Python Comment Block

Planet Python - Thu, 2021-11-25 09:15

ItsMyCode |

Comments are a piece of text in a computer program that provides more information on the source code written. Like every other programming language, Python has three different types of comments: single-line comments, multi-line comments, and documentation string.

Introduction to Python Comment Block

Comments are used to explain the source code. Comments are mainly used for the following purposes.

  1. Improve Code readability
  2. Testing the code
  3. Explaining the code or Metadata of the project
  4. Prevent execution of specific code blocks

For example, let’s say you have written complex business logic, formulas, algorithms, etc. Then we need to document it using the comments that explain what the code does, thus improving the readability of the code in Python.

Python interpreter ignores the comments while executing the code and only interprets the code.

Types of comments in Python

There are three kinds of comments we can use in Python. 

  1. Single-line comments
  2. Multi-line comments
  3. Documentation strings, aka docstrings

Let us look into details on how to use these comments in Python code with examples.

Single-line comments

Single-line comments, also called block comments, start with a hash sign (#) followed by a single space and a text string.

The hash (#) works with only a single line of code and not on multi-line code. 

Let’s take an example to demonstrate single-line comments in Python.

# This is a single line comment example print("Hello World") Inline comments

If you place the comment in the same line as a statement, you will have an inline comment.

Like single-line comments, inline comments also begin with a hash (#) sign and are followed by a space and the comment text. 

Let’s take an example to demonstrate inline comments in Python.

print("Hello World") # This is a example of inline comment Multi-line comments

Usually, in other languages like C, C#, Java, etc., we can write a multi-line comment as shown below.

/* This is a comment block which supports Multi-line code */

But you cannot do this in Python.

Python does not have any built-in mechanism for commenting out multiple lines. However, there are different ways to achieve this in Python.

Using Multiple Hashtags (#)

We can use multiple hashtags to write multi-line comments in Python. Each line that has a hash sign(#) is considered as a single line comment.

# This is how we can acheive # Multi-line comments in Python print("Hello World") Python docstrings

Documentation strings, also called docstrings, are the string literal denoted with triple quotes that occur as the first statement in a module, function, class, or method definition.

Note: We can also use triple “”” quotations to create docstrings.

Single line docstrings

Let’s take an example to demonstrate single line docstring. 

def Add(a,b): '''Takes two number as input and returns sum of 2 numbers''' return a+b

Inside the triple quotation marks is the docstring of the function Add() as it appears right after its definition.

Multi-line docstrings

The multi-line docstring can span across multiple lines of code starts with triple quotes(“””) and ends with triple quotes (“””).

The following example shows you how to use multi-line docstrings:

def Add(a,b): '''Takes two number as input Adds a and b Returns sum of a and b as output ''' return a+b print(Add(5,6))

The post Python Comment Block appeared first on ItsMyCode.

Categories: FLOSS Project Planets

Annertech: Decoupled websites are secure, fast and cost-effective – perfect for councils

Planet Drupal - Thu, 2021-11-25 08:05

This article will break down the ins and outs of decoupling, set out the pros and cons, and tell you why Annertech should be your first port of call.

Categories: FLOSS Project Planets

KDE Floating Panels: PULL REQUEST DONE! And Next Projects!

Planet KDE - Thu, 2021-11-25 06:10
💸💸 IF YOU WANT TO HELP ME DO MORE MERGE REQUESTS: :D 💸💸 Patreon: https://www.patreon.com/niccolove Youtube: https://www.youtube.com/channel/UCONH73CdRXUjlh3-DdLGCPw/join Paypal: https://paypal.me/niccolove Stay in the loop: https://t.me/veggeroblog My website is https://niccolo.venerandi.com and if you want to contact me, my telegram handle is [at] veggero.
Categories: FLOSS Project Planets

Mike Gabriel: Touching Firefox on Linux

Planet Debian - Thu, 2021-11-25 05:01

More as a reminder to myself, but possibly also helpful to other people who want to use Firefox on a tablet running Debian...

Without the below adjustment, finger gestures in Firefox running on a tablet result in image moving, text highlighting, etc. (operations related to copy+paste). Not the intuitively expected behaviour...

If you use e.g. GNOME on Wayland for your tablet and want to enable touch functionalities in Firefox, then switch the whole browser to native Wayland rendering. This line in ~/.profile seems to help:

export MOZ_ENABLE_WAYLAND=1

If you use a desktop environment running on top of X.Org, then make sure you have added the following line to ~/.profile:

export MOZ_USE_XINPUT2=1

Logout/login again and Firefox should be scrollable with 2-finger movements up and down, zooming in and out also works then.

light+love
Mike (aka sunweaver at debian.org)

Categories: FLOSS Project Planets

Python GUIs: Using Layouts to Position Widgets in PyQt6 — Use layouts to effortlessly position widgets within the window (updated for PyQt6)

Planet Python - Thu, 2021-11-25 04:00

So far we've successfully created a window, and we've added a widget to it. However we normally want to add more than one widget to a window, and have some control over where it ends up. To do this in Qt we use layouts. There are 4 basic layouts available in Qt, which are listed in the following table.

Layout Behavior QHBoxLayout Linear horizontal layout QVBoxLayout Linear vertical layout QGridLayout In indexable grid XxY QStackedLayout Stacked (z) in front of one another

You can also design and lay out your interface graphically using the Qt designer. Here we're using code, so you can understand the underlying system.

As you can see, there are three positional layouts available in Qt. The VBoxLayout, QHBoxLayout and QGridLayout. In addition there is also QStackedLayout which allows you to place widgets one on top of the other within the same space, yet showing only one layout at a time.

Before we start we need a simple application outline. Save the following code in a file named app.py -- we'll modify this application to experiment with different layouts.

python import sys from PyQt6.QtWidgets import QApplication, QMainWindow, QWidget from PyQt6.QtGui import QPalette, QColor class MainWindow(QMainWindow): def __init__(self): super(MainWindow, self).__init__() self.setWindowTitle("My App") app = QApplication(sys.argv) window = MainWindow() window.show() app.exec()

To make it easier to visualize the layouts, we'll first create a simple custom widget that displays a solid color of our choosing. This will help to distinguish widgets that we add to the layout. Add the following code to your file as a new class at the top level --

python class Color(QWidget): def __init__(self, color): super(Color, self).__init__() self.setAutoFillBackground(True) palette = self.palette() palette.setColor(QPalette.ColorRole.Window, QColor(color)) self.setPalette(palette)

In this code we subclass QWidget to create our own custom widget Color. We accept a single parameter when creating the widget — color (a str). We first set .setAutoFillBackground to True to tell the widget to automatically fill its background with the window cooler. Next we get the current palette (which is the global desktop palette by default) and change the current QPalette.Window color to a new QColor described by the value color we passed in. Finally we apply this palette back to the widget. The end result is a widget that is filled with a solid color, that we specified when we created it.

If you find the above confusing, don't worry too much. We'll cover custom widgets in more detail later. For now it's sufficient that you understand that calling you can create a solid-filled red widget by doing the following:

python Color('red')

First let's test our new Color widget by using it to fill the entire window in a single color. Once it’s complete we can add it to the QMainWindow using .setCentralWidget and we get a solid red window.

python class MainWindow(QMainWindow): def __init__(self): super(MainWindow, self).__init__() self.setWindowTitle("My App") widget = Color('red') self.setCentralWidget(widget)

Run it! The window will appear, filled completely with the color red. Notice how the widget expands to fill all the available space.

Next we'll look at each of the available Qt layouts in turn. Note that to add our layouts to the window we will need a dummy QWidget to hold the layout.

QVBoxLayout vertically arranged widgets

With QVBoxLayout you arrange widgets one above the other linearly. Adding a widget adds it to the bottom of the column.

A QVBoxLayout, filled from top to bottom.

Let’s add our widget to a layout. Note that in order to add a layout to the QMainWindow we need to apply it to a dummy QWidget. This allows us to then use .setCentralWidget to apply the widget (and the layout) to the window. Our colored widgets will arrange themselves in the layout, contained within the QWidget in the window. First we just add the red widget as before.

python class MainWindow(QMainWindow): def __init__(self): super(MainWindow, self).__init__() self.setWindowTitle("My App") layout = QVBoxLayout() layout.addWidget(Color('red')) widget = QWidget() widget.setLayout(layout) self.setCentralWidget(widget)

Run it! Notice the border now visible around the red widget. This is the layout spacing — we'll see how to adjust that later.

If you add a few more colored widgets to the layout you’ll notice that they line themselves up vertical in the order they are added.

python class MainWindow(QMainWindow): def __init__(self): super(MainWindow, self).__init__() self.setWindowTitle("My App") layout = QVBoxLayout() layout.addWidget(Color('red')) layout.addWidget(Color('green')) layout.addWidget(Color('blue')) widget = QWidget() widget.setLayout(layout) self.setCentralWidget(widget) QHBoxLayout horizontally arranged widgets

QHBoxLayout is the same, except moving horizontally. Adding a widget adds it to the right hand side.

A QHBoxLayout, filled from left to right.

To use it we can simply change the QVBoxLayout to a QHBoxLayout. The boxes now flow left to right.

python class MainWindow(QMainWindow): def __init__(self): super(MainWindow, self).__init__() self.setWindowTitle("My App") layout = QHBoxLayout() layout.addWidget(Color('red')) layout.addWidget(Color('green')) layout.addWidget(Color('blue')) widget = QWidget() widget.setLayout(layout) self.setCentralWidget(widget) Nesting layouts

For more complex layouts you can nest layouts inside one another using .addLayout on a layout. Below we add a QVBoxLayout into the main QHBoxLayout. If we add some widgets to the QVBoxLayout, they’ll be arranged vertically in the first slot of the parent layout.

python class MainWindow(QMainWindow): def __init__(self): super(MainWindow, self).__init__() self.setWindowTitle("My App") layout1 = QHBoxLayout() layout2 = QVBoxLayout() layout3 = QVBoxLayout() layout2.addWidget(Color('red')) layout2.addWidget(Color('yellow')) layout2.addWidget(Color('purple')) layout1.addLayout( layout2 ) layout1.addWidget(Color('green')) layout3.addWidget(Color('red')) layout3.addWidget(Color('purple')) layout1.addLayout( layout3 ) widget = QWidget() widget.setLayout(layout1) self.setCentralWidget(widget)

Run it! The widgets should arrange themselves in 3 columns horizontally, with the first column also containing 3 widgets stacked vertically. Experiment!

You can set the spacing around the layout using .setContentMargins or set the spacing between elements using .setSpacing.

python layout1.setContentsMargins(0,0,0,0) layout1.setSpacing(20)

The following code shows the combination of nested widgets and layout margins and spacing. Experiment with the numbers til you get a feel for them.

python class MainWindow(QMainWindow): def __init__(self): super(MainWindow, self).__init__() self.setWindowTitle("My App") layout1 = QHBoxLayout() layout2 = QVBoxLayout() layout3 = QVBoxLayout() layout1.setContentsMargins(0,0,0,0) layout1.setSpacing(20) layout2.addWidget(Color('red')) layout2.addWidget(Color('yellow')) layout2.addWidget(Color('purple')) layout1.addLayout( layout2 ) layout1.addWidget(Color('green')) layout3.addWidget(Color('red')) layout3.addWidget(Color('purple')) layout1.addLayout( layout3 ) widget = QWidget() widget.setLayout(layout1) self.setCentralWidget(widget) QGridLayout widgets arranged in a grid

As useful as they are, if you try and using QVBoxLayout and QHBoxLayout for laying out multiple elements, e.g. for a form, you’ll find it very difficult to ensure differently sized widgets line up. The solution to this is QGridLayout.

A QGridLayout showing the grid positions for each location.

QGridLayout allows you to position items specifically in a grid. You specify row and column positions for each widget. You can skip elements, and they will be left empty.

Usefully, for QGridLayout you don't need to fill all the positions in the grid.

A QGridLayout with unfilled slots.

python class MainWindow(QMainWindow): def __init__(self): super(MainWindow, self).__init__() self.setWindowTitle("My App") layout = QGridLayout() layout.addWidget(Color('red'), 0, 0) layout.addWidget(Color('green'), 1, 0) layout.addWidget(Color('blue'), 1, 1) layout.addWidget(Color('purple'), 2, 1) widget = QWidget() widget.setLayout(layout) self.setCentralWidget(widget) QStackedLayout multiple widgets in the same space

The final layout we’ll cover is the QStackedLayout. As described, this layout allows you to position elements directly in front of one another. You can then select which widget you want to show. You could use this for drawing layers in a graphics application, or for imitating a tab-like interface. Note there is also QStackedWidget which is a container widget that works in exactly the same way. This is useful if you want to add a stack directly to a QMainWindow with .setCentralWidget.

QStackedLayout — in use only the uppermost widget is visible, which is by default the first widget added to the layout.

QStackedLayout, with the 2nd (1) widget selected and brought to the front.

python from PyQt6.QtWidgets import QStackedLayout # add this import class MainWindow(QMainWindow): def __init__(self): super().__init__() self.setWindowTitle("My App") layout = QStackedLayout() layout.addWidget(Color("red")) layout.addWidget(Color("green")) layout.addWidget(Color("blue")) layout.addWidget(Color("yellow")) layout.setCurrentIndex(3) widget = QWidget() widget.setLayout(layout) self.setCentralWidget(widget)

QStackedWidget is exactly how tabbed views in applications work. Only one view ('tab') is visible at any one time. You can control which widget to show at any time by using .setCurrentIndex() or .setCurrentWidget() to set the item by either the index (in order the widgets were added) or by the widget itself.

Below is a short demo using QStackedLayout in combination with QButton to to provide a tab-like interface to an application:

python import sys from PyQt6.QtCore import Qt from PyQt6.QtWidgets import ( QApplication, QHBoxLayout, QLabel, QMainWindow, QPushButton, QStackedLayout, QVBoxLayout, QWidget, ) from layout_colorwidget import Color class MainWindow(QMainWindow): def __init__(self): super().__init__() self.setWindowTitle("My App") pagelayout = QVBoxLayout() button_layout = QHBoxLayout() self.stacklayout = QStackedLayout() pagelayout.addLayout(button_layout) pagelayout.addLayout(self.stacklayout) btn = QPushButton("red") btn.pressed.connect(self.activate_tab_1) button_layout.addWidget(btn) self.stacklayout.addWidget(Color("red")) btn = QPushButton("green") btn.pressed.connect(self.activate_tab_2) button_layout.addWidget(btn) self.stacklayout.addWidget(Color("green")) btn = QPushButton("yellow") btn.pressed.connect(self.activate_tab_3) button_layout.addWidget(btn) self.stacklayout.addWidget(Color("yellow")) widget = QWidget() widget.setLayout(pagelayout) self.setCentralWidget(widget) def activate_tab_1(self): self.stacklayout.setCurrentIndex(0) def activate_tab_2(self): self.stacklayout.setCurrentIndex(1) def activate_tab_3(self): self.stacklayout.setCurrentIndex(2) app = QApplication(sys.argv) window = MainWindow() window.show() app.exec()

A custom tab-like interface implemented using QStackedLayout.

Helpfully. Qt actually provide a built-in TabWidget that provides this kind of layout out of the box - albeit in widget form. Below the tab demo is recreated using QTabWidget:

python import sys from PyQt6.QtCore import Qt from PyQt6.QtWidgets import ( QApplication, QLabel, QMainWindow, QPushButton, QTabWidget, QWidget, ) from layout_colorwidget import Color class MainWindow(QMainWindow): def __init__(self): super().__init__() self.setWindowTitle("My App") tabs = QTabWidget() tabs.setTabPosition(QTabWidget.West) tabs.setMovable(True) for n, color in enumerate(["red", "green", "blue", "yellow"]): tabs.addTab(Color(color), color) self.setCentralWidget(tabs) app = QApplication(sys.argv) window = MainWindow() window.show() app.exec()

A tabbed interface using the QTabWidget.

As you can see, it's a little more straightforward — and a bit more attractive! You can set the position of the tabs using the cardinal directions, toggle whether tabs are moveable with .setMoveable. You'll notice that the macOS tab bar looks quite different to the others -- by default on macOS tabs take on a pill or bubble style. On macOS this is typically used for tabbed configuration panels. For documents, you can turn on document mode to give slimline tabs similar to what you see on other platforms. This option has no effect on other platforms.

python tabs = QTabWidget() tabs.setDocumentMode(True)

QTabWidget in document mode on macOS.

We'll encounter more of these advanced widgets later.

For an in-depth guide to building Python GUIs with PyQt6 see my book, Create GUI Applications with Python & Qt6.

Categories: FLOSS Project Planets

Dirk Eddelbuettel: nanotime 0.3.4 on CRAN: Maintenance Update

Planet Debian - Wed, 2021-11-24 17:00

Another (minor) nanotime release, now at version 0.3.4, arrived at CRAN overnight. It exports some nanoperiod functionality via a C++ header, and Leonardo and I will use this in an upcoming package that we hope to talk about a little more in a few days. It also adds a few as.character.*() methods that had not been included before.

nanotime relies on the RcppCCTZ package for (efficient) high(er) resolution time parsing and formatting up to nanosecond resolution, and the bit64 package for the actual integer64 arithmetic. Initially implemented using the S3 system, it has benefitted greatly from a rigorous refactoring by Leonardo who not only rejigged nanotime internals in S4 but also added new S4 types for periods, intervals and durations.

The NEWS snippet adds more details.

Changes in version 0.3.4 (2021-11-24)
  • Added a few more as.character conversion function (Dirk)

  • Expose nanoperiod functionality via header file for use by other packages (Leonardo in #95 fixing #94).

Thanks to CRANberries there is also a diff to the previous version. More details and examples are at the nanotime page; code, issue tickets etc at the GitHub repository.

If you like this or other open-source work I do, you can now sponsor me at GitHub.

This post by Dirk Eddelbuettel originated on his Thinking inside the box blog. Please report excessive re-aggregation in third-party for-profit settings.

Categories: FLOSS Project Planets

Gbyte blog: Simple XML Sitemap 4.0.0 has been released!

Planet Drupal - Wed, 2021-11-24 12:30

After six months of work I'm delighted to tag the first stable release of the 4.x branch of the (Not-so-) Simple XML Sitemap module.

The project is in a really good place right now. At the moment of writing, drupal.org reports it being actively used on around 90k of Drupal 8/9 websites while having 0 open bug reports. This either means you people are lousy bug reporters, or we are doing a descent job at responding. :)

Module rewrite with developers/integrators in mind

4.x makes much greater use of Drupal's entity API dropping some of its very specific chaining API. Feel free to take a look at the roadmap ticket for specifics.

New UI

We now have a much nicer UI for creating, editing and sorting sitemaps as well as sitemap types.

API usage

In a nutshell, sitemap variants are now sitemap entities. These are of a sitemap type (sitemap type entity) that is defined by URL generator plugins as well as sitemap generator plugins.

Categories: FLOSS Project Planets

Python for Beginners: Breadth First Traversal in Python

Planet Python - Wed, 2021-11-24 10:49

A graph is a non linear data structure. We often use graphs to represent different real world objects like maps and networks. In this article, we will study breadth first traversal to print all the vertices in a graph. We will also implement the breadth first traversal algorithm in Python.

What is breadth first traversal?

Breadth first traversal is a graph traversal algorithm to print all the vertices in a graph. In this algorithm, we start with a vertex and print its value. Then we print all the neighbors of the current vertex. After that, we select every neighbor of the current vertex and print all of its neighbors. This process continues until all of the vertices in the graph are printed.

Let us understand this process by performing a breadth first traversal on the following graph.

Image of a Graph

Suppose that we start from vertex A.

After printing vertex A, we will print all of its neighbor vertices i.e. B, D, E, and F.

After printing B,D, E, and F, we will select one of these vertices. Let us select D.

As D has no neighbor that needs to be printed, we will move back to A and choose another neighbor of A. Let us select E.

As E has no neighbor that needs to be printed, we will move back to A and choose another neighbor of A. Let us select F.

As F has no neighbor that needs to be printed, we will move back to A and choose another neighbor of A. Let us select B.

Now, we will print all the neighbors of B that have not been printed yet. Hence, we will print C. 

At this point, you can observe that all of the vertices in the graph have been printed in the order A, B, D, E, F, C . So, we will terminate the algorithm. 

Algorithm for breadth first traversal 

The algorithm for depth first traversal of a graph is implemented using a queue data structure. Here, we will assume that we have a connected graph. In other words, we can reach each vertex of the graph from the starting vertex.

We will maintain a queue to store the vertices that have not been printed and a list to store the visited vertices. After that we will process the graph using the following algorithm.

  1. Create an empty queue Q to store the vertices that have not been printed.
  2. Create an empty list L to store the visited vertices.
  3. Insert source vertex into the Q and L.
  4. If Q is empty, Go to 9. Else go to 5.
  5. Take out a vertex v from Q.
  6. Print the vertex v.
  7. Insert all the neighbors of v that are not in L into Q as well as L.
  8. Go to 4.
  9. Stop.

This Algorithm can be demonstrated using the following source code for the graph given in the figure above.

from queue import Queue graph = {'A': ['B', 'D', 'E', 'F'], 'D': ['A'], 'B': ['A', 'F', 'C'], 'F': ['B', 'A'], 'C': ['B'], 'E': ['A']} print("Given Graph is:") print(graph) def BFS_Algorithm(input_graph, source): Q = Queue() visited_vertices = list() Q.put(source) visited_vertices.append(source) while not Q.empty(): vertex = Q.get() print("At:",vertex) print("Printing vertex:",vertex) for u in input_graph[vertex]: if u not in visited_vertices: print("At vertex, adding {} to Q and visited_vertices".format(vertex, u)) Q.put(u) visited_vertices.append(u) print("visited vertices are: ", visited_vertices) print("BFS traversal of graph with source A is:") BFS_Algorithm(graph, "A")

Output:

Given Graph is: {'A': ['B', 'D', 'E', 'F'], 'D': ['A'], 'B': ['A', 'F', 'C'], 'F': ['B', 'A'], 'C': ['B'], 'E': ['A']} BFS traversal of graph with source A is: At: A Printing vertex: A At vertex, adding A to Q and visited_vertices At vertex, adding A to Q and visited_vertices At vertex, adding A to Q and visited_vertices At vertex, adding A to Q and visited_vertices visited vertices are: ['A', 'B', 'D', 'E', 'F'] At: B Printing vertex: B At vertex, adding B to Q and visited_vertices visited vertices are: ['A', 'B', 'D', 'E', 'F', 'C'] At: D Printing vertex: D visited vertices are: ['A', 'B', 'D', 'E', 'F', 'C'] At: E Printing vertex: E visited vertices are: ['A', 'B', 'D', 'E', 'F', 'C'] At: F Printing vertex: F visited vertices are: ['A', 'B', 'D', 'E', 'F', 'C'] At: C Printing vertex: C visited vertices are: ['A', 'B', 'D', 'E', 'F', 'C']

In the output, you can observe that the vertices have been printed in the order A, B, D, E, F, and C.

Implementation of Breadth first traversal in Python

As we have discussed the general idea for breadth first traversal of a graph and observed how the algorithm works using the python program, we can implement the breadth first traversal algorithm as follows.

from queue import Queue graph = {'A': ['B', 'D', 'E', 'F'], 'D': ['A'], 'B': ['A', 'F', 'C'], 'F': ['B', 'A'], 'C': ['B'], 'E': ['A']} print("Given Graph is:") print(graph) def BFS(input_graph, source): Q = Queue() visited_vertices = list() Q.put(source) visited_vertices.append(source) while not Q.empty(): vertex = Q.get() print(vertex, end= " ") for u in input_graph[vertex]: if u not in visited_vertices: Q.put(u) visited_vertices.append(u) print("BFS traversal of graph with source A is:") BFS(graph, "A")

Output:

Given Graph is: {'A': ['B', 'D', 'E', 'F'], 'D': ['A'], 'B': ['A', 'F', 'C'], 'F': ['B', 'A'], 'C': ['B'], 'E': ['A']} BFS traversal of graph with source A is: A B D E F C Conclusion

In this article, we have discussed the breadth first traversal algorithm for a fully connected graph in python. To read more about other algorithms, you can read this article on In-order tree traversal in Python.

The post Breadth First Traversal in Python appeared first on PythonForBeginners.com.

Categories: FLOSS Project Planets

Mike Driscoll: Python Black Friday / Cyber Monday Sales 2021

Planet Python - Wed, 2021-11-24 08:30

Lots of companies do sales on Black Friday, sometimes for the entire week. I am going to link to Black Friday sales for Python-related materials, including my own, in this article.

I am having a sale where you can get $10 off if you use the following coupon: black21. This coupon works on any of my Python books on Gumroad

This code will work on my newest book, Automating Excel with Python. It will also work on older titles like Pillow: Image Processing with Python and Creating GUI Applications with wxPython among others.

Other Python Sales

There are other indie authors and regular publishers that are having sales. Here are a few:

My friend, Sundeep, is also having some Python book sales:

1) Practice Python Projects (https://learnbyexample.gumroad.com/l/py_projects/blackfriday…) ebook is free (normal price $10)

2) Learn by example Python bundle (https://learnbyexample.gumroad.com/l/python-bundle/blackfriday…) is $2 (normal price $12) - includes Python re(gex)?, 100 Page Python Intro and Practice Python Projects

3) All Books Bundle (https://learnbyexample.gumroad.com/l/all-books/blackfriday…) is $5 (normal price $22) - includes all three Python books mentioned in the bundle above

These sales from Sundeep are good until the end of November

Trey Hunner is keeping track of all the Python sales too on his site, so check it out too so that you don't miss anything

The post Python Black Friday / Cyber Monday Sales 2021 appeared first on Mouse Vs Python.

Categories: FLOSS Project Planets

Agiledrop.com Blog: The power of open-source communities

Planet Drupal - Wed, 2021-11-24 08:23

In this article, we explore 4 key elements of open-source communities that drive the success of their respective projects.

READ MORE
Categories: FLOSS Project Planets

Floating Panel Devlog: States, Transitions, Thickness... I had been optimistic.

Planet KDE - Wed, 2021-11-24 07:23
💸💸 Help me contribute to KDE and do these videos: 💸💸 Patreon: https://www.patreon.com/niccolove Youtube: https://www.youtube.com/channel/UCONH73CdRXUjlh3-DdLGCPw/join Paypal: https://paypal.me/niccolove Stay in the loop: https://t.me/veggeroblog My website is https://niccolo.venerandi.com and if you want to contact me, my telegram handle is [at] veggero.
Categories: FLOSS Project Planets

Pages