QTabWidget not styled correctly when using StyleSheet - python-3.x

I am not able to properly style the QTabWidget using the StyleSheet in Qt Designer.
How can I style the tab buttons, the close buttons on them? There is a weird white bezel at the bottom? How can I remove them?
Here is the style sheet for it:
background-color: rgb(58, 68, 102);
border-radius: 4;
border-style: none;
Here is a minimal reproducible example:
The Python file:
from PyQt5.QtWidgets import QApplication, QMainWindow
from PyQt5 import uic
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
#Loading teh ui file
uic.loadUi('sir.ui', self)
QApp = QApplication([])
window = MainWindow()
window.show()
QApp.exec()
The ui file:
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>805</width>
<height>625</height>
</rect>
</property>
<property name="windowTitle">
<string>MainWindow</string>
</property>
<property name="styleSheet">
<string notr="true">background-color: rgb(38, 43, 68);</string>
</property>
<widget class="QWidget" name="centralwidget">
<widget class="QTabWidget" name="tabWidget">
<property name="geometry">
<rect>
<x>10</x>
<y>0</y>
<width>781</width>
<height>581</height>
</rect>
</property>
<property name="focusPolicy">
<enum>Qt::TabFocus</enum>
</property>
<property name="contextMenuPolicy">
<enum>Qt::DefaultContextMenu</enum>
</property>
<property name="acceptDrops">
<bool>true</bool>
</property>
<property name="styleSheet">
<string notr="true">background-color: rgb(58, 68, 102);
border-radius: 4;
border-style: none;</string>
</property>
<property name="tabPosition">
<enum>QTabWidget::North</enum>
</property>
<property name="currentIndex">
<number>0</number>
</property>
<property name="elideMode">
<enum>Qt::ElideRight</enum>
</property>
<property name="tabsClosable">
<bool>true</bool>
</property>
<property name="movable">
<bool>true</bool>
</property>
<widget class="QWidget" name="tab_2">
<attribute name="title">
<string>Home</string>
</attribute>
</widget>
</widget>
</widget>
<widget class="QMenuBar" name="menubar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>805</width>
<height>21</height>
</rect>
</property>
</widget>
<widget class="QStatusBar" name="statusbar"/>
</widget>
<resources/>
<connections/>
</ui>
Here is the current state:

Related

Why that property don't apply on the QMenu widget?

I try to make that GUI, but when I try to apply "styleSheet" property it's not working. The code it's working well, I can load that UI in python, but when I try the style of menuFile don't seems to be applied.
There is my code from .ui file:
<widget class="QMenuBar" name="menubar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>1280</width>
<height>21</height>
</rect>
</property>
<property name="autoFillBackground">
<bool>false</bool>
</property>
<property name="styleSheet">
<string notr="true">QMenuBar{color:white;}</string>
</property>
<widget class="QMenu" name="menuFile">
<property name="styleSheet">
<string notr = "true">
QMenu {background-color:black;}
QMenu:hover { background-color: red; }
</string>
</property>
<property name="title">
<string>File</string>
</property>
</widget>
<widget class="QMenu" name="menuEdit">
<property name = "styleSheet">
<string notr="true"></string>
</property>
<property name="title">
<string>Edit</string>
</property>
</widget>
<widget class="QMenu" name="menuHelp">
<property name="title">
<string>Help</string>
</property>
</widget>
<widget class="QMenu" name="menuWindow">
<property name="title">
<string>Window</string>
</property>
</widget>
<widget class="QMenu" name="menuLayout">
<property name="title">
<string>Layout</string>
</property>
</widget>
<widget class="QMenu" name="menuPresentation">
<property name="title">
<string>Presentation</string>
</property>
</widget>
<widget class="QMenu" name="menuRender">
<property name="title">
<string>Render</string>
</property>
</widget>

Why is the window not rendering correctly?

I'm trying to develop an application using GNOME Builder and Glade, but it will not render.
Here's the .ui code.
https:// pastebin.com/JbfqC6Mt
The window is supposed to render 3 buttons in a row.
i'm not sure if it's my version of something or what. I need this to work as i am one of the main programmers of this project.
`<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.38.2 -->
<interface>
<requires lib="gtk" version="4.0"/>
<requires lib="gtk+" version="3.10"/>
<template class="EmucratelauncherWindow" parent="GtkApplicationWindow">
<property name="can-focus">False</property>
<property name="default-width">600</property>
<property name="default-height">300</property>
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="spacing">100</property>
<property name="homogeneous">True</property>
<child>
<object class="GtkButton">
<property name="label" translatable="yes">button</property>
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="receives-default">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkButton">
<property name="label" translatable="yes">button</property>
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="receives-default">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkButton">
<property name="label" translatable="yes">button</property>
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="receives-default">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">2</property>
</packing>
</child>
</object>
</child>
<child type="titlebar">
<object class="GtkHeaderBar" id="header_bar">
<property name="can-focus">False</property>
<child type="end">
<object class="GtkMenuButton">
<property name="can-focus">False</property>
<property name="receives-default">False</property>
<child>
<placeholder/>
</child>
</object>
</child>
</object>
</child>
</template>
</interface>`

How do I make web requests in a PyQt5 application without hanging the UI? [duplicate]

This question already has answers here:
PyQt5 loading spinner halts on post request
(1 answer)
pyqt5 in not responding state when calling the url
(1 answer)
Closed 1 year ago.
I have a PyQt5 application running in Python 3.7 that makes a lot of web request, but no more than one or two at a time. Most requests are quick, but sometimes take several seconds. The whole UI hangs until the requests complete. I have a full sample application below to demonstrate this.
Looking around, some people recommend using QThread but if I try to do that, I get complaints about accessing UI objects from the wrong thread. That method also prevents me from returning the web response to the caller. In the sample code below, the response is only used to print the status code, but in the actual application the JSON responses are parsed and used. Most answers to this question I find are more than five years old, often referencing PyQt4 or older, or referencing packages that are now obsolete such as grequests or request-threads. Some people reference httpx (still in beta) or aiohttp, which has its own event loop and doesn't always play nice inside PyQt5 applications.
The sample is as stripped down as possible to demonstrate the problem. if you click "Make Request" and immediately click on "Click Counter" you'll see that the counter doesn't increase until the web request has completed. This is not surprising given that the request is blocking the Qt event loop.
How can I just simply get the current code to work where the requests are submitted and managed asynchronously, but still being able to pass a response back to the caller?
Here is test.py:
import sys
from datetime import datetime
import requests
from PyQt5 import QtWidgets, uic
from requests import RequestException
class UI(QtWidgets.QMainWindow):
def __init__(self):
super(UI, self).__init__()
uic.loadUi('test.ui', self)
self.web = WebManager(self)
self.issue_request_button.clicked.connect(self.issue_request)
self.issue_click_button.clicked.connect(self.click_counter)
self.show()
def click_counter(self):
self.click_count_label.setText(str(int(self.click_count_label.text()) + 1))
def issue_request(self):
r = self.web.issue_get(self.request_url.text())
print(r.status_code if r is not None else 'No successful response')
class WebManager:
def __init__(self, gui):
self.gui = gui
def issue_get(self, url_request):
try:
start = datetime.now()
headers = {'Accept': 'application/json', 'Content-Type': 'application/json'}
r = requests.get(url_request, headers=headers)
self.fill_request_response_info(r, datetime.now() - start)
return r
except RequestException as e:
print(f'Request failed with an Exception of type {type(e).__name__}')
return None
def fill_request_response_info(self, response, total_request_time):
request = response.request
self.gui.request_url_textbox.setText(request.method + ' ' + request.url)
self.gui.request_headers_textbox.setText('\n'.join(k + ':' + v for k, v in request.headers.items()))
self.gui.response_status_textbox.setText(f'{response.status_code} {response.reason}')
self.gui.response_elapsed_time_textbox.setText(f'{response.elapsed} / {total_request_time}')
self.gui.response_headers_textbox.setText('\n'.join(k + ':' + v for k, v in response.headers.items()))
self.gui.response_body_textbox.setText(response.content.decode('utf-8'))
app = QtWidgets.QApplication(sys.argv)
window = UI()
app.exec()
and here is the UI file that it needs test.ui:
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>750</width>
<height>734</height>
</rect>
</property>
<property name="windowTitle">
<string>Test Window</string>
</property>
<widget class="QWidget" name="centralwidget">
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QPushButton" name="issue_request_button">
<property name="text">
<string>Make Request</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>URL:</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="request_url">
<property name="text">
<string>https://archive.org/advancedsearch.php?q=subject:google+sheets&output=json</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="QPushButton" name="issue_click_button">
<property name="text">
<string>Click Counter</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="click_count_label">
<property name="text">
<string>0</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item>
<widget class="QGroupBox" name="http_request_groupBox">
<property name="title">
<string>HTTP Request</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QLabel" name="req_url_label">
<property name="text">
<string>Request URL:</string>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QLineEdit" name="request_url_textbox"/>
</item>
</layout>
</item>
<item>
<widget class="QLabel" name="req_headers_label">
<property name="text">
<string>Request Headers:</string>
</property>
</widget>
</item>
<item>
<widget class="QTextEdit" name="request_headers_textbox"/>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="http_response_groupBox">
<property name="title">
<string>HTTP Response</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2" stretch="0,0,1,0,1">
<item>
<layout class="QGridLayout" name="gridLayout" rowstretch="0,0">
<item row="0" column="0">
<widget class="QLabel" name="http_status_label">
<property name="text">
<string>HTTP Status:</string>
</property>
</widget>
</item>
<item row="0" column="3">
<widget class="QLabel" name="elapsed_time_label">
<property name="text">
<string>Elapsed Time:</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLineEdit" name="response_status_textbox"/>
</item>
<item row="1" column="3">
<widget class="QLineEdit" name="response_elapsed_time_textbox"/>
</item>
</layout>
</item>
<item>
<widget class="QLabel" name="response_headers_label">
<property name="text">
<string>Response Headers:</string>
</property>
</widget>
</item>
<item>
<widget class="QTextEdit" name="response_headers_textbox"/>
</item>
<item>
<widget class="QLabel" name="response_body_label">
<property name="text">
<string>Response Body:</string>
</property>
</widget>
</item>
<item>
<widget class="QTextEdit" name="response_body_textbox"/>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
</widget>
<tabstops>
<tabstop>issue_request_button</tabstop>
<tabstop>request_url</tabstop>
<tabstop>issue_click_button</tabstop>
<tabstop>request_url_textbox</tabstop>
<tabstop>request_headers_textbox</tabstop>
<tabstop>response_status_textbox</tabstop>
<tabstop>response_elapsed_time_textbox</tabstop>
<tabstop>response_headers_textbox</tabstop>
<tabstop>response_body_textbox</tabstop>
</tabstops>
<resources/>
<connections/>
</ui>

How to make a one-window program with GTK, python and glade?

I'd like to write a program that has one main window and if I click on a button it changes the content of the window (or something similar) and the user can go back after that to the "home page".
I'm using python3, gtk3 and glade on Ubuntu 19.04.
Here's the example.glade XML file
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.22.1 -->
<interface>
<requires lib="gtk+" version="3.20"/>
<object class="GtkApplicationWindow" id="main">
<property name="can_focus">False</property>
<child>
<placeholder/>
</child>
<child>
<object class="GtkButton" id="button">
<property name="label" translatable="yes">button</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
</object>
</child>
</object>
</interface>
And here's the Python3 file
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import gi
import os
os.chdir('/home/sources')
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk
class app:
def __init__(self):
self.gladefile = 'example.glade'
self.builder = Gtk.Builder()
self.builder.add_from_file(self.gladefile)
self.builder.connect_signals(self)
self.window = self.builder.get_object('main')
elf.window = self.builder.get_object('button')
self.window.show()
if __name__ == '__main__':
main = app()
Gtk.main()
I'd like to change the window (but in the same window) to this when the button is pressed
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.22.1 -->
<interface>
<requires lib="gtk+" version="3.20"/>
<object class="GtkApplicationWindow" id="main">
<property name="can_focus">False</property>
<child>
<placeholder/>
</child>
<child>
<object class="GtkNotebook" id="notebook">
<property name="visible">True</property>
<property name="can_focus">True</property>
<child>
<object class="GtkButton" id="but1">
<property name="label" translatable="yes">button</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
</object>
</child>
<child type="tab">
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">page 1</property>
</object>
<packing>
<property name="tab_fill">False</property>
</packing>
</child>
<child>
<object class="GtkButton" id="but2">
<property name="label" translatable="yes">button</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
</object>
<packing>
<property name="position">1</property>
</packing>
</child>
<child type="tab">
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">page 2</property>
</object>
<packing>
<property name="position">1</property>
<property name="tab_fill">False</property>
</packing>
</child>
<child>
<object class="GtkButton" id="but3">
<property name="label" translatable="yes">button</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
</object>
<packing>
<property name="position">2</property>
</packing>
</child>
<child type="tab">
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">page 3</property>
</object>
<packing>
<property name="position">2</property>
<property name="tab_fill">False</property>
</packing>
</child>
</object>
</child>
</object>
</interface>
Here is a possible solution using Gtk.Stack
The glade file:
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.22.1 -->
<interface>
<requires lib="gtk+" version="3.20"/>
<object class="GtkImage" id="image1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="stock">gtk-go-back</property>
</object>
<object class="GtkWindow" id="window">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="title" translatable="yes">window</property>
<property name="window_position">center</property>
<property name="default_width">500</property>
<property name="default_height">400</property>
<signal name="destroy" handler="on_window_destroy" swapped="no"/>
<child>
<placeholder/>
</child>
<child>
<object class="GtkStack" id="stack">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkButton" id="home_button">
<property name="label" translatable="yes">Notebook page</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<signal name="clicked" handler="button_clicked" swapped="no"/>
</object>
<packing>
<property name="name">page0</property>
<property name="title" translatable="yes">page0</property>
</packing>
</child>
<child>
<object class="GtkBox" id="notebook_box">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkButton">
<property name="label" translatable="yes">Home</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="image">image1</property>
<property name="always_show_image">True</property>
<signal name="clicked" handler="home_clicked" swapped="no"/>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkNotebook" id="notebook">
<property name="visible">True</property>
<property name="can_focus">True</property>
<child>
<object class="GtkButton" id="but1">
<property name="label" translatable="yes">button</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
</object>
</child>
<child type="tab">
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">page 1</property>
</object>
<packing>
<property name="tab_fill">False</property>
</packing>
</child>
<child>
<object class="GtkButton" id="but2">
<property name="label" translatable="yes">button</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
</object>
<packing>
<property name="position">1</property>
</packing>
</child>
<child type="tab">
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">page 2</property>
</object>
<packing>
<property name="position">1</property>
<property name="tab_fill">False</property>
</packing>
</child>
<child>
<object class="GtkButton" id="but3">
<property name="label" translatable="yes">button</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
</object>
<packing>
<property name="position">2</property>
</packing>
</child>
<child type="tab">
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">page 3</property>
</object>
<packing>
<property name="position">2</property>
<property name="tab_fill">False</property>
</packing>
</child>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="name">page1</property>
<property name="title" translatable="yes">page1</property>
<property name="position">1</property>
</packing>
</child>
</object>
</child>
</object>
</interface>
The python file:
#!/usr/bin/env python
import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk
UI_FILE = "file.glade"
class GUI:
def __init__(self):
self.builder = Gtk.Builder()
self.builder.add_from_file(UI_FILE)
self.builder.connect_signals(self)
window = self.builder.get_object('window')
window.show_all()
def on_window_destroy(self, window):
Gtk.main_quit()
def home_clicked (self, button):
stack = self.builder.get_object('stack')
home_button = self.builder.get_object('home_button')
stack.set_visible_child(home_button)
def button_clicked (self, button):
stack = self.builder.get_object('stack')
notebook_box = self.builder.get_object('notebook_box')
stack.set_visible_child(notebook_box)
app = GUI()
Gtk.main()

How to use gtk::DrawingArea?

I am trying to build a GUI in Rust using GTK, Cairo and Glade. I want to draw a playing field using gtk::DrawingArea but I do not know how to use it. I have this:
extern crate cairo;
extern crate gtk;
use gtk::*;
fn main() {
gtk::init().unwrap(); //init gtk before using it
let glade_src = include_str!("Glade_gui.glade"); //build the glade gui
let builder = gtk::Builder::new_from_string(glade_src);
//get widgets from the gui
let draw_area: gtk::DrawingArea = builder.get_object("zeichenbrett").unwrap();
let window: gtk::Window = builder.get_object("fenster").unwrap();
let size = (600, 600); //define the size for the image
let style_context: gtk::StyleContext = draw_area.get_style_context().unwrap(); //get the style context from the drawing area
let surface: cairo::ImageSurface =
cairo::ImageSurface::create(cairo::Format::ARgb32, size.0, size.1).unwrap(); //build a new ImageSurface to draw on
let context: cairo::Context = cairo::Context::new(&surface); //build a new cairo context from that ImageSurface to draw on
//just a blue area
context.set_source_rgb(0.0, 0.0, 1.0);
context.paint();
context.stroke();
gtk::functions::render_background(
&style_context,
&context,
0.0,
0.0,
size.0 as f64,
size.1 as f64,
); //here I thought that I drew the context cairo::Context to the drawingArea but it seems to do nothing.
window.show_all();
gtk::main();
}
It compiles and runs, but no playing field is shown on the window.
I think I am not using the render_background function correctly, but I do not know how to do it right.
Here is the Glade_gui.glade file:
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.20.0 -->
<interface>
<requires lib="gtk+" version="3.20"/>
<object class="GtkWindow" id="fenster">
<property name="can_focus">False</property>
<property name="title" translatable="yes">Reise nach Jerusalem</property>
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="spacing">5</property>
<property name="homogeneous">True</property>
<child>
<object class="GtkButton" id="links">
<property name="label" translatable="yes">Left</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkButton" id="rechts">
<property name="label" translatable="yes">Right</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkButton" id="quit">
<property name="label" translatable="yes">Quit</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">2</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkDrawingArea" id="zeichenbrett">
<property name="visible">True</property>
<property name="can_focus">False</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
</child>
</object>
</interface>
As a note, I have no experience in Rust, so I'll use mainly C examples.
You are attempting to render your GUI before starting gtk::main. The proper way to implement a GTK+ GUI is to add your widgets, connect their draw signal (and any other necessary signals) to your own draw callback function, then run gtk::main.
As an example, take the documentation's simple GtkDrawingArea example found here. In this example, g_signal_connect is used to connect the draw signal to the draw_callback callback function. This way, when the widget is actually created by gtk::main, it will draw your desired image on it.
Your draw_callback function will get a Cairo context as a parameter. You will do all your drawing on that context, so there is no need to create your own. This is also demonstrated in the docs by the use of the pointer cr in the parameters of draw_callback.
All your drawing needs to be done in the draw callback function. It will get called anytime an update is necessary (including creation of the GtkDrawingArea widget), or you can force an update by emitting the queue_draw signal.
The C docs can be a great help even when using a different language, especially if your chosen language doesn't have comprehensive documentation.
Also, the recommended modern way to create a GTK+ application is to use GtkApplication. You may want to look into that.

Resources