Related
I have a for loop as follows:
import MDAnalysis as mda
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
from tqdm import tqdm as tq
import MDAnalysis.analysis.pca as pca
import random
def PCA_projection(pdb,dcd,atomgroup):
u = mda.Universe(pdb,dcd)
PSF_pca = pca.PCA(u, select=atomgroup)
PSF_pca.run(verbose=True)
n_pcs = np.where(PSF_pca.results.cumulated_variance > 0.95)[0][0]
atomgroup = u.select_atoms(atomgroup)
pca_space = PSF_pca.transform(atomgroup, n_components=n_pcs)
PC1_proj = [pca_space[i][0] for i in range(len(pca_space))]
PC2_proj = [pca_space[i][1] for i in range(len(pca_space))]
return PC1_proj, PC2_proj
def Read_bias_potential(bias_potential):
Bias_potential = pd.read_csv(bias_potential)
Bias_potential = Bias_potential['En-User']
Bias_potential = Bias_potential.values.tolist()
W = [math.exp((-1 * i) / (0.001987*300)) for i in Bias_potential]
return W
def Bin(PC1_prj, PC2_prj, frame_num, min_br1, max_br1, min_br2, max_br2, bin_num, W):
#import pdb;pdb.set_trace()
data1 = PC1_prj[0:frame_num]
bins1 = np.linspace(min_br1, max_br1, bin_num)
bins1 = np.round(bins1,2)
digitized1 = np.digitize(data1, bins1)
binc1 = np.arange(min_br1 + (max_br1 - min_br1)/2*bin_num,
max_br1 + (max_br1 - min_br1)/2*bin_num, (max_br1 - min_br1)/bin_num, dtype = float)
binc1 = np.around(binc1,3)
data2 = PC2_prj[0:frame_num]
bins2 = np.linspace(min_br2, max_br2, bin_num)
bins2 = np.round(bins2,2)
digitized2 = np.digitize(data2, bins2)
binc2 = np.arange(min_br2 + (max_br2 - min_br2)/2*bin_num, max_br2 + (max_br2 - min_br2)/2*bin_num, (max_br2 - min_br2)/bin_num, dtype = float)
binc2 = np.around(binc2,3)
w_array = np.zeros((bin_num,bin_num))
for j in range(frame_num):
w_array[digitized1[j]][digitized2[j]] += (W[digitized1[j]] + W[digitized2[j]])
for m in range(bin_num):
for n in range(bin_num):
if w_array[m][n] == 0:
w_array[m][n] = 1e-100
return w_array, binc1, binc2
def gaussian(Sj1,Slj1,Sj2,Slj2,count):
sigma1 = 0.5
sigma2 = 0.5
Kb = 0.001987204
T = 300
h0 = 0.0001
g = 0
C1 = 0
C2 = 0
for i in range((np.where(Slj2 == Sj2)[0][0] - 5),(np.where(Slj2 == Sj2)[0][0] + 6)):
if i < 0:
C2 = i + 1000
elif i > 999:
C2 = i - 1000
else:
C2 = i
for j in range((np.where(Slj1 == Sj1)[0][0] - 5),(np.where(Slj2 == Sj2)[0][0] + 6)):
if j < 0:
C1 = j + 1000
elif j > 999:
C1 = j -1000
else:
C1 = j
g = g + count[C2,C1] * h0 * np.exp( (-(Sj1 - Slj1[C1]) ** 2 / (2 * sigma1 ** 2)) + (-(Sj2 - Slj2[C2]) ** 2 / (2 * sigma2 ** 2)) )
return np.exp(-g / (Kb * T))
def resampling(binc1, binc2, w_array):
# import pdb;pdb.set_trace()
l =1000
F = np.zeros((l,l))
count = np.zeros((l,l))
Wn = w_array
for i in tq(range(10000000)):
SK1 = random.choice(binc1)
SK2 = random.choice(binc2)
SL1 = random.choice(binc1)
SL2 = random.choice(binc2)
while SK1 == SL1:
SL1 = random.choice(binc1)
while SK2 == SL2:
SL2 = random.choice(binc2)
F[np.where(binc2 == SK2)[0][0]][np.where(binc1 == SK1)[0][0]] = gaussian(SK1,binc1,SK2,binc2,count)
F[np.where(binc2 == SK2)[0][0]][np.where(binc1 == SK1)[0][0]] = gaussian(SL1,binc1,SL2,binc2,count)
W_SK = Wn[np.where(binc2 == SK2)[0][0]][np.where(binc1 == SK1)[0][0]] * F[np.where(binc2 == SK2)[0][0]][np.where(binc1 == SK1)[0][0]]
W_SL = Wn[np.where(binc2 == SL2)[0][0]][np.where(binc1 == SL1)[0][0]] * F[np.where(binc2 == SL2)[0][0]][np.where(binc1 == SL1)[0][0]]
if W_SK <= W_SL:
SK1 = SL1
SK2 = SL2
else:
a = random.random()
if W_SL/W_SK >= a:
SK1 = SL1
SK2 = SL2
else:
SK1 = SK1
SK2 = SK2
#print('SK =',SK)
count[np.where(binc2 == SK2)[0][0]][np.where(binc1 == SK1)[0][0]] += 1
return F
where binc1 and binc2 are two np.arrays, gaussian is a gaussian fxn I defined, is there anyway I can speed up this for loop? Now 1000000 steps takes approximately 50 mins. I am thinking about using pytorch but I got no idea on how to do it. Any suggestions would be helpful!
Thanks
I tried to use pytorch, like put all the variables on gpu but it only does worse.
So I'm trying to make this game called 4 in a row or something, I'm quite new to pygame and python in general so yeah...
It says it crashes because get closest isn't getting the vpos value but I did set it as the y array...
import pygame
pygame.init()
screen = pygame.display.set_mode([620, 520])
running = True
Emptygray = (220,220,220)
Bordergray = (105, 105, 105)
y = []
x = []
m = 0
n = 0
urgo = True
for i in range(0,30):
x.append(0)
y.append(0)
m = 0
n = 0
def getclosest(mousey, vpos):
r = 0
for i in range(0,5):
s = abs(mousey[1] - vpos[i])
if r < s: r = i
return r
print(len(x))
while running:
screen.fill((202, 164, 114))
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
for i in range(0,6):
for j in range(0,5):
a = 60
b = 60
pygame.draw.circle(screen, Bordergray, ( a + 100 * i, b + 100 * j), 47)
if n < 30: x[n] = [a + 100 * i]
if n <= 30: n += 1
pygame.draw.circle(screen, Emptygray, ( a + 100 * i, b + 100 * j), 44)
if m < 30: y[m] = [b + 100 * j]
if m <= 30: m += 1
if urgo:
for event in pygame.event.get():
if event.type == pygame.MOUSEBUTTONUP:
print(mousey = getclosest(pygame.mouse.get_pos()), vpos = y[0:4])
pygame.display.flip()
#print ("x:", x)
#print ("y:", y)
Exception has occurred: TypeError
getclosest() missing 1 required positional argument: 'vpos'
File "C:\Users\NOEL\Desktop\Folders\Python\Game\3.py", line 43, in <module>
print(mousey = getclosest(pygame.mouse.get_pos()), vpos = y[0:4])
print(mousey = getclosest(pygame.mouse.get_pos()), vpos = y[0:4])
should be
print(mousey = getclosest(pygame.mouse.get_pos(), vpos = y[0:4]))
import time, timeit, random, pygame, sys
from math import *
import numpy as np
XDIM = 1000 #window length
YDIM = 1200 #window breadth
WINSIZE = [XDIM, YDIM]
EPSILON = 7.0 #threshold
NUMNODES = 10000
GOAL_RADIUS = 10
MIN_DISTANCE_TO_ADD = 1.0 #incremental distance
GAME_LEVEL = 1
RANDOM_COUNT = 10000
pygame.init()
fpsClock = pygame.time.Clock()
#screen parameters and variable
screen = pygame.display.set_mode(WINSIZE)
pygame.display.set_caption('Q-learning')
white = 255, 240, 200
black = 20, 20, 40
red = 255, 0, 0
blue = 0, 255, 0
green = 0, 0, 255
cyan = 0,255,255
class Node:
def __init__(self):
self.x = x
self.y = y
self.cost = 0.0
self.parent = None
self.children = set()
class RRT(__Q_table):
def __init__(self, start, goal,
obstacleList, incremental_dist = 15.0,
learning_rate=20, max_iterations = 2000, randArea= None):
self.start = Node(start[0], start[1])
self.end = Node(goal[0], goal[1])
self.Xrand = randArea[0]
self.Yrand = randArea[1]
self.margin = incremental_distance
self.learning_rate = learning_rate
self.obstacleList = obstacleList
self.max_iterations = max_iterations
def planning(self, animation = True):
self.NodeList = {0 : self.start}
i=0
while True:
print(i)
if set(self.start).intersection(obstacleList) == None:
self.NodeList.append(self.start)
print(self.NodeList)
rnd = self.get_random_point()
nearest_index = self.GetNearestListIndex(rnd)
new_node = self.steer(rnd, nearest_index)
if self.Collision_check(new_node, self.obstacleList):
near_indices = self.find_near_nodes(new_node, 5)
new_node = self.choose_parent(new_node, near_indices)
self.nodeList[i+100] = new_node
self.rewire(i+100, new_node, near_indices)
self.nodeList[new_node.parent].children.add(i+100)
if len(self.NodeList) > self.max_iterations:
leaves = [keys for key, node in self.NodeList.items]
if len(leaves) > 1:
index = leaves[random.randint(0, len(leaves)-1)]
self.NodeList[self.NodeList[index].paresnt].children.discard(index)
self.NodeList.pop(index)
else:
leaves = [key for key, node in self.NodeList.items() if len(node.children)==0]
index = leaves[random.randint(0, len(leaves) -1)]
self.NodeList[self.NodeList[index].parent].children.discard(index)
self.NodeList.pop(index)
if animation == True:
self.DrawGraph(rnd)
for event in pygame.event.get():
if event.type == pygame.MOUSEBUTTONDOWN:
if event.button == 1:
self.obstacleList.append((event.pos[0], event.pos[1], 30, 30))
self.path_validation()
elif event.button == 3:
self.end.x = event.pos[0]
self.end.y = event.pos[1]
self.path_validation()
def path_validation(self):
lastIndex = self.get_the_best_last_index()
if lastIndex and set(lastIndex).intersection(obstacleList) == None:
while self.NodeList[lastIndex].parent is not None:
nodeIndex = lastIndex
lastIndex = self.NodeList[lastIndex].parent
dx = self.NodeList[nodeIndex].x - self.NodeList[lastIndex].x
dy = self.NodeList[nodeIndex].y - self.NodeList[lastIndex].y
d = math.sqrt.atan2(dx**2 + dy**2)
theta = math.atan2(dy, dx)
if not self.check_collision_extend(self.NodeList[lastIndex].x,self.NodeList[lastIndex].y, theta, d):
self.NodeList[lastIndex].children.discard(nodeIndex)
self.eliminate_branch(nodeIndex)
def eliminate_brach(self, nodeIndex):
safenodesList = []
if set(nodeIndex).intersection(obstacleList) == None:
safenodesList.append(nodeIndex)
for not_safe in safenodesList[nodeIndex].children:
self.eliminate_branch(not_safe)
self.NodeList.pop(nodeIndex)
def choose_parent(self,new_node,nearest_index):
if len(nearest_index) == 0:
return new_node
if Current_point == nearest_index and self.CollisionCheck(new_node, obstacleList):
Current_point = new_node
return Current_point
distanceList = []
for i in near_indices:
dx = new_node.x - self.NodeList[i].x
dy = new_node.y - self.NodeList[i].y
d = math.sqrt(dx **2 + dy **2)
theta = math.atan2(dy, dx)
if self.check_collision_extend(self.NodeList[i].x, self.NodeList[i].y, theta, d):
distanceList.append(self.NodeList[i].cost + d)
else:
distanceList.append(float("inf"))
minimum_cost = min(distanceList)
minimum_index = near_indices[distacelist.index(minimum_cost)]
if minimum_cost == float("inf"):
print("minimum_cost is INFINITE")
return Current_point
Current_point.cost = minimum_cost
Current_point.parent = minimum_index
Current_point_with_maximum_Q_value = self.max_Q_nextvalue(Current_point)
return Current_point.cost, Current_point.parent, Current_point_with_maximum_Q_value
def steer(self, rnd, nearest_index):
nearest_node = self.NodeList[nearest_index]
theta = math.atan2(rnd[1] - nearest_node.y, rnd[0] - nearest_node.x)
new_node = Node(nearest_node.x , nearest_node.y)
new_node.x += incremental_distance * math.cos(theta)
new_node.y += incremental_distance * math.sin(theta)
new_node.cost = nearest_node.cost + incremental_distance
new_node.parent = nearest_index
return new_node
def get_random_point(self, Current_point=None):
self.Current_point = Current_point
if random.randint(0, 100) > self.learning_rate:
rnd = [random.uniform(0, Xrand), random.uniform(0, yrand)]
elif random.randint(0, 100) <= RANDOM_COUNT:
Current_point = max_Q_action(Current_point)
rnd = random_action(Current_point)
else:
rnd = [self.end.x, self.end.y]
return rnd
def get_best_last_index(self):
disglist = [(key, self.calc_dist_to_goal(node.x, node.y)) for key, node in self.NodeList.items()]
goal_indices = [key for key, distance in disglist if distance <= self.margin]
if len(goal_indices) == 0:
return None
minimum_cost = min([self.NodeList[key].cost for key in goal_indices])
for i in goal_indices:
if self.NodeList[i].cost == minimum_cost:
return i
return None
def gen_final_course(self, goal_indices):
path = [[self.end.x, self.end.y]]
while self.NodeList[goal_indices].parent is not None:
node = self.NodeList[goal_indices]
path.append([node.x, node.y])
goal_indices = node.parent
path.append([self.start.x, self.start.y])
return path
def calc_dist_to_goal(self, x, y):
return np.linalg.norm([x - self.end.x, y - self.end.y])
def find_near_nodes(self, new_node, value):
r = self.margin * value
distanceList = np.subtract( np.array([ (node.x, node.y) for node in self.NodeList.values() ]), (new_node.x,new_node.y))**2
distanceList = np.sum(distanceList, axis=1)
near_indices = np.where(distanceList <= r ** 2)
near_indices = np.array(list(self.NodeList.keys()))[near_indices]
return nearinds
def rewire(self, newNodeInd, new_node, near):
nnode = len(self.NodeList)
for i in nearinds:
nearNode = self.nodeList[i]
dx = new_node.x - nearNode.x
dy = new_node.y - nearNode.y
d = math.sqrt(dx ** 2 + dy ** 2)
scost = new_node.cost + d
if near_node.cost > scost:
theta = math.atan2(dy, dx)
if self.check_collision_extend(nearNode.x, nearNode.y, theta, d):
self.NodeList[nearNode.parent].children.discard(i)
nearNode.parent = newNodeInd
nearNode.cost = scost
new_node.children.add(i)
def check_collision_extend(self, nix, niy, theta, d):
tmpNode = Node(nix,niy)
for i in range(int(d/5)):
tmpNode.x += 5 * math.cos(theta)
tmpNode.y += 5 * math.sin(theta)
if not self.CollisionCheck(tmpNode, self.obstacleList):
return False
return True
def DrawGraph(self, rnd=None):
screen.fill((255, 255, 255))
for node in self.NodeList.values():
if node.parent is not None:
pygame.draw.line(screen,(0,255,0),[self.NodeList[node.parent].x,self.NodeList[node.parent].y],[node.x,node.y])
for node in self.NodeList.values():
if len(node.children) == 0:
pygame.draw.circle(screen, (255,0,255), [int(node.x),int(node.y)], 2)
for(sx,sy,ex,ey) in self.obstacleList:
pygame.draw.rect(screen,(0,0,0), [(sx,sy),(ex,ey)])
pygame.draw.circle(screen, (255,0,0), [self.start.x, self.start.y], 10)
pygame.draw.circle(screen, (0,0,255), [self.end.x, self.end.y], 10)
lastIndex = self.get_best_last_index()
if lastIndex is not None:
path = self.gen_final_course(lastIndex)
ind = len(path)
while ind > 1:
pygame.draw.line(screen,(255,0,0),path[ind-2],path[ind-1])
ind-=1
pygame.display.update()
def Get_nearest_list_index(self, rnd):
distanceList = np.subtract( np.array([ (node.x, node.y) for node in self.NodeList.values() ]), (rnd[0],rnd[1]))**2
distanceList = np.sum(distanceList, axis=1)
minimum_index = list(self.NodeList.keys())[np.argmin(distancelist)]
return minimum_index
def Collision_check(self, node, obstacleList):
for(sx,sy,ex,ey) in obstacleList:
sx,sy,ex,ey = sx+2,sy+2,ex+2,ey+2
if node.x > sx and node.x < sx+ex:
if node.y > sy and node.y < sy+ey:
return False
return True
def main():
print("start RRT path planning")
obstacleList = [
(400, 380, 400, 20),
(400, 220, 20, 180),
(500, 280, 150, 20),
(0, 500, 100, 20),
(500, 450, 20, 150),
(400, 100, 20, 80),
(100, 100, 100, 20)
]
rrt = RRT(obstacleList = obstacleList, start =[10, 580], goal = [540, 150],
randArea = [XDIM, YDIM])
path = rrt.Planning(animation=show_animation)
if __name__ == '__main__':
main()
The error is -
TypeError Traceback (most recent call last)
<ipython-input-1-6e62c6da9819> in <module>
531
532 if __name__ == '__main__':
--> 533 main()
534
<ipython-input-1-6e62c6da9819> in main()
525
526 rrt = RRT(obstacleList = obstacleList, start =[10, 580], goal = [540, 150],
--> 527 randArea = [XDIM, YDIM])
528
529 path = rrt.planning(animation=show_animation)
<ipython-input-1-6e62c6da9819> in __init__(self, start, goal, obstacleList, incremental_dist, learning_rate, max_iterations, randArea)
249 learning_rate=20, max_iterations = 2000, randArea= None):
250
--> 251 self.start = Node(start[0], start[1])
252 self.end = Node(goal[0], goal[1])
253 self.Xrand = randArea[0]
TypeError: init() takes 1 positional argument but 3 were given
I am trying to write a code for motion planning in python using pygame module. I encountered this error given above. I even tried reducing the parameters into the constructor init() but it did not work out.
Please note that here I am not trying to do inheritance.
Thanks
Replace
path = rrt.Planning(animation=show_animation)
With
path = rrt.planning(animation=show_animation)
Edit: after the addition of the tracelog
Your error is that you provided two arguments to create a Node:
self.start = Node(start[0], start[1])
But its __init__ method expects none to be passed:
class Node:
def __init__(self):
I'm working on a simulation that shows how the entire group move as objects with different velocities move in a line. Below one is the trackback, and I can't see what is the problem here.
Traceback (most recent call last): File "C:\Users\JeeWoo Kim\Desktop\practice2.py", line 98, in <module>
map_grid = MapGrid(map_width, map_height)
File "C:\Users\JeeWoo Kim\Desktop\practice2.py", line 16, in __init__
self.outside_terrain_grid = self._generate_empty_noise_grid(self.map_width, self.map_height)
File "C:\Users\JeeWoo Kim\Desktop\practice2.py", line 49, in
_generate_empty_noise_grid
new_map_grid[x][y] += _individual_decision(self, sum_velocity, number_count)
NameError: name '_individual_decision' is not defined
Code -
import pygame
import random
import math
import time
import numpy
class MapGrid():
def __init__(self, map_width, map_height):
# set map values
self.map_width = map_width
self.map_height = map_width
# generate outside rooms
self.outside_terrain_grid = self._generate_empty_noise_grid(self.map_width, self.map_height)
def _generate_empty_noise_grid(self, map_width, map_height):
new_map_grid = [] # create our new list
for x in range(map_width):
new_map_grid.append([]) # add our columns to the array
for y in range(map_height):
if y < 20:
new_map_grid[x].append(random.choice([0,1,2])) # fill in our rows
else:
new_map_grid[x].append(0)
number_count = 0
sum_velocity = 0
for y in range(map_height):
if new_map_grid[x][y] != 0:
number_count +=1
sum_velocity += new_map_grid[x][y]
new_map_grid[x][y] += _individual_decision(self, sum_velocity, number_count)
return new_map_grid
def _individual_decision(self, sum_velocity, number_count):
mu = 1.5 # average
sigma = 0.125 # standard deviation
average_velocity = sum_velocity / number_count
critical_number =np.random.normal(mu, sigma)
if average_velocity - critical_number < 0:
return 1
elif average_velocity - critical_number >= 0:
return 2
def _generate_outside_terrain(self, empty_outside_terrain_grid, number_of_generations):
'''
creates a bubble effect with cellular automaton
'''
grid = empty_outside_terrain_grid
number_of_generations = number_of_generations
for x in range(number_of_generations):
next_grid = []
for column_index, column in enumerate(grid):
next_column = []
next_grid.append(next_column)
for tile_index, tile in enumerate(column):
top_mid = grid[column_index][tile_index - 1]
mid = grid[column_index][tile_index]
d_top_mid = grid[column_index][tile_index + 1] % 2
d_mid = grid[column_index][tile_index] % 2
v_top_mid = math.floor((grid[column_index][tile_index+1] + 1) / 2)
v_mid = math.floor((grid[column_index][tile_index] + 1) / 2)
if d_mid <= v_top_mid:
grid[column_index][tile_index] == d_mid * 2 # vi = di
next_column+v_mid.append(grid[column_index][tile_index])
elif d_mid > v_top_mid:
if numpy.random.randint(0,2) == 1:
next_grid+1[next_column.append(grid[column_index][tile_index])]
grid = next_grid
return next_grid
if __name__ == '__main__':
# general map stats
map_width = 140
map_height = 30
# start with one generation
tile_size = 8
map_grid = MapGrid(map_width, map_height)
#print map_grid.outside_terrain_grid
pygame.init()
screen = pygame.display.set_mode((map_width * tile_size,map_height * tile_size))
zero_tile = pygame.Surface((1, 1))
zero_tile.fill((0,0,0))
one_tile = pygame.Surface((1, 1))
one_tile.fill((255,255,255))
two_tile = pygame.Surface((1,1))
two_tile.fill((255,0,0))
three_tile = pygame.Surface((1,1))
three_tile.fill((0,0,204))
four_tile = pygame.Surface((1,1))
four_tile.fill((0,255,0))
colors = {0: zero_tile, 1: one_tile, 2:two_tile}
background = pygame.Surface((map_width * tile_size,map_height * tile_size))
clock = pygame.time.Clock()
first_gen = True
timer = 12
running = True
while running == True:
clock.tick(3)
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
if first_gen:
themap = map_grid.outside_terrain_grid
else:
themap = map_grid._generate_outside_terrain(themap, 1)
for column_index, column in enumerate(themap):
for tile_index, tile in enumerate(column):
screen.blit(colors[tile], (tile_index * tile_size, column_index * tile_size))
pygame.display.flip()
if first_gen:
timer -= 1
if timer < 0:
first_gen = False
pygame.quit()
_individual_decision() is an instance method, you should call it as - self._individual_decision() . Code -
new_map_grid[x][y] += self._individual_decision(sum_velocity, number_count)
Also, you should not send self as the first arguement, just send the other arguments.
I have some information (a list of participants to an event) which I want to print out easily. No need for fancy layout, just a table with several columns, and if possible a drawn line in between the lines of text for better readability. Will need to print landscape to make it all fit (can be done via a GtkPageSetup).
I'm using Python, and I'm on Linux so will have to use the GtkPrintUnixDialog interface. I've been searching on Internet but can't find any example on how this could possibly be achieved.
To simplify the problem: it's for my own use only, so known paper size (A4).
The problem that I have is basically two-fold: 1) create a properly formatted text, suitable for printing, and 2) send this to the printer.
Any suggestions on where to start? Or better, complete examples?
I search for my old print examples, but for a start:
You could write to pdf surface, and print pdf, or
put the drawing code on on_print function. Note, it does not print what you see, but what you draw on print surface. Draw the context like a regular cairo context, but a few methods are not available(don't fit in print context) while others, like new page, are added. If I find the example, I will come with a answer more self-explanatory.
Edit: find an ex:
def on_button_clicked(self, widget):
ps = Gtk.PaperSize.new_custom("cc", "cc", 210, 297, Gtk.Unit.MM)
st = Gtk.PrintSettings()
s = Gtk.PageSetup()
s.set_paper_size(ps)
s.set_bottom_margin(4.3, Gtk.Unit.MM)
s.set_left_margin(4.3, Gtk.Unit.MM)
s.set_right_margin(4.3, Gtk.Unit.MM)
s.set_top_margin(4.3, Gtk.Unit.MM)
s.set_orientation(Gtk.PageOrientation.LANDSCAPE)
# ret = Gtk.print_run_page_setup_dialog(self, s, st)
pd = Gtk.PrintOperation()
pd.set_n_pages(1)
pd.set_default_page_setup(s)
pd.connect("begin_print", self.bg)
pd.connect("draw_page", self.draw_page)
# print(ret, s, st)
pd.set_export_filename("test.pdf")
result = pd.run(Gtk.PrintOperationAction.EXPORT, None) #play with action, but for test export first; if it's ok, then action.PRINT
print (result) # handle errors etc.
# Gtk.PaperSize.free(ps) - not needed in py
the above may be on button press or whatever
def draw_page (self, operation, context, page_number):
end = self.layout.get_line_count()
cr = context.get_cairo_context()
cr.set_source_rgb(0, 0, 0)
i = 0
start = 0
start_pos = 0
iter = self.layout.get_iter()
while 1:
if i >= start:
line = iter.get_line()
print(line)
_, logical_rect = iter.get_line_extents()
# x_bearing, y_bearing, lwidth, lheight = logical_rect
baseline = iter.get_baseline()
if i == start:
start_pos = 12000 / 1024.0 # 1024.0 is float(pango.SCALE)
cr.move_to(0 / 1024.0, baseline / 1024.0 - start_pos)
PangoCairo.show_layout_line(cr, line)
i += 1
if not (i < end and iter.next_line()):
break
That's just a basic example. Note that layout is a pango layout:
self.layout = cx.create_pango_layout()
self.layout.set_width(int(w / 4 * Pango.SCALE))
self.layout.set_text(text, len(text))
num_lines = self.layout.get_line_count()
page_height = 0
self.layout.set_font_description(Pango.FontDescription("Georgia Bold 12"))
k = 0
for line in range(num_lines):
if k == 4:
self.layout.set_font_description(Pango.FontDescription("Georgia 10"))
layout_line = self.layout.get_line(line)
ink_rect, logical_rect = layout_line.get_extents()
lheight = 1200
line_height = lheight / 1024.0 # 1024.0 is float(pango.SCALE)
page_height += line_height
k += 1
print ("page_height ", page_height)
copy/paste functional example:
#!/usr/bin/python
from gi.repository import Gtk, Pango, PangoCairo
import cairo
text = '''
Text.
I have some information (a list of participants to an event) which I
want to print out easily.
No need for fancy layout,
just a table with several columns,
and if possible a drawn line in between the lines of
text for better readability.
'''
class MyWindow(Gtk.Window):
def __init__(self):
Gtk.Window.__init__(self, title="Hello World Printing")
self.button = Gtk.Button(label="Print A Rectangle")
self.button.connect("clicked", self.on_button_clicked)
self.add(self.button)
def on_button_clicked(self, widget):
ps = Gtk.PaperSize.new_custom("cc", "cc", 210, 297, Gtk.Unit.MM)
st = Gtk.PrintSettings()
s = Gtk.PageSetup()
s.set_paper_size(ps)
s.set_bottom_margin(4.3, Gtk.Unit.MM)
s.set_left_margin(4.3, Gtk.Unit.MM)
s.set_right_margin(4.3, Gtk.Unit.MM)
s.set_top_margin(4.3, Gtk.Unit.MM)
s.set_orientation(Gtk.PageOrientation.LANDSCAPE)
# ret = Gtk.print_run_page_setup_dialog(self, s, st)
pd = Gtk.PrintOperation()
pd.set_n_pages(1)
pd.set_default_page_setup(s)
pd.connect("begin_print", self.bg)
pd.connect("draw_page", self.draw_page)
# print(ret, s, st)
pd.set_export_filename("test.pdf")
result = pd.run(Gtk.PrintOperationAction.EXPORT, None)
print (result) # handle errors etc.
# Gtk.PaperSize.free(ps)
def bg(self, op, cx):
w = cx.get_width()
h = cx.get_height()
self.layout = cx.create_pango_layout()
self.layout.set_width(int(w / 4 * Pango.SCALE))
self.layout.set_text(text, len(text))
num_lines = self.layout.get_line_count()
page_height = 0
self.layout.set_font_description(Pango.FontDescription("Georgia Bold 12"))
k = 0
for line in range(num_lines):
if k == 4:
self.layout.set_font_description(Pango.FontDescription("Georgia 10"))
layout_line = self.layout.get_line(line)
ink_rect, logical_rect = layout_line.get_extents()
# print(logical_rect, ink_rect)
# x_bearing, y_bearing, lwidth, lheight = logical_rect
lheight = 1200
line_height = lheight / 1024.0 # 1024.0 is float(pango.SCALE)
page_height += line_height
# page_height is the current location on a page.
# It adds the the line height on each pass through the loop
# Once it is greater then the height supplied by context.get_height
# it marks the line and sets the current page height back to 0
k += 1
print ("page_height ", page_height)
def box(self, w, h, x, y, cx):
w, h = int(w), int(h)
cx.set_font_size(100)
cx.set_source_rgb(0, 0, 0)
cx.rectangle(x, y, w, h)
cx.stroke()
yy = 120
cx.select_font_face("Times", 0, 1)
ex = cx.text_extents("TEGOLA ROMÂNIA SRL")[2]
cx.move_to(w / 2 - ex / 2 + x, 105 + y)
cx.show_text("TEGOLA ROMÂNIA SRL")
ex = cx.text_extents("Str. Plevnei, nr. 5, Buzău")[2]
cx.move_to(w / 2 - ex / 2 + x, 210 + y)
cx.show_text("Str. Plevnei, nr. 5, Buzău")
ex = cx.text_extents("Tel.: 0238/710.280")[2]
cx.move_to(w / 2 - ex / 2 + x, 320 + y)
cx.show_text("Tel.: 0238/710.280")
ex = cx.text_extents("Fax : 0238/710021")[2]
cx.move_to(w / 2 - ex / 2 + x, 415 + y)
cx.show_text("Fax : 0238/710021")
cx.set_font_size(90)
cx.move_to(x + 120, 520 + y)
ex = cx.text_extents("Compoziție:")[2]
cx.show_text("Compoziție:")
cx.select_font_face("Times", 0, 0)
cx.move_to(x + 125 + ex, 520 + y)
cx.show_text("Polimer bituminos, liant și")
cx.move_to(x + 5, 620 + y)
cx.show_text("material de umplutură de înaltă calitate.")
cx.move_to(x + 5, 720 + y)
cx.show_text("Nu conține gudron.")
cx.move_to(x + 5, 800 + y)
cx.select_font_face("Times", 0, 1)
ex = cx.text_extents("Instrucțiuni de utilizare:")[2]
cx.show_text("Instrucțiuni de utilizare:")
cx.select_font_face("Times", 0, 0)
cx.move_to(x + 10 + ex, 800 + y)
cx.show_text("Suprafețele se")
def draw_page1(self, operation, context, page_nr=None):
ctx = context.get_cairo_context()
w = context.get_width()
h = context.get_height()
ww, hh = int(w / 4), int(h / 2)
self.k = 0
for x in range(2):
for y in range(4):
self.box(ww, hh, y * ww, x * hh, ctx)
self.k += 1
print(ctx.get_font_matrix())
def draw_page (self, operation, context, page_number):
end = self.layout.get_line_count()
cr = context.get_cairo_context()
cr.set_source_rgb(0, 0, 0)
i = 0
start = 0
start_pos = 0
iter = self.layout.get_iter()
while 1:
if i >= start:
line = iter.get_line()
print(line)
_, logical_rect = iter.get_line_extents()
# x_bearing, y_bearing, lwidth, lheight = logical_rect
baseline = iter.get_baseline()
if i == start:
start_pos = 12000 / 1024.0 # 1024.0 is float(pango.SCALE)
cr.move_to(0 / 1024.0, baseline / 1024.0 - start_pos)
PangoCairo.show_layout_line(cr, line)
i += 1
if not (i < end and iter.next_line()):
break
win = MyWindow()
win.connect("delete-event", Gtk.main_quit)
win.show_all()
Gtk.main()
Don't forget to change action to Gtk.PrintOperationAction.PRINT for real printing.