Canvas đồ họa vector Python
Bước đầu tiên để tạo các tiện ích tùy chỉnh trong PyQt5 là hiểu các hoạt động đồ họa bitmap (dựa trên pixel). Tất cả các tiện ích tiêu chuẩn tự vẽ dưới dạng ảnh bitmap trên một "bức vẽ" hình chữ nhật tạo thành hình dạng của tiện ích. Khi bạn hiểu cách thức hoạt động của nó, bạn có thể vẽ bất kỳ tiện ích nào bạn thích Show Một bitmap là một lưới pixel hình chữ nhật, trong đó mỗi pixel được lưu trữ riêng lẻ dưới dạng một số bit. Tương phản với đồ họa véc tơ, nơi hình ảnh được lưu trữ dưới dạng một loạt các hướng dẫn vẽ được lặp lại để tạo thành hình ảnh Trong hướng dẫn này, chúng ta sẽ xem xét 1 — API của Qt để thực hiện các thao tác đồ họa bitmap và cơ sở để vẽ các vật dụng của riêng bạn. Chúng ta sẽ thực hiện một số thao tác vẽ cơ bản và cuối cùng kết hợp tất cả lại với nhau để tạo ứng dụng Paint nhỏ của riêng chúng taQPainterCác thao tác vẽ bitmap trong Qt được xử lý thông qua lớp 1. Đây là một giao diện chung có thể được sử dụng để vẽ trên các bề mặt khác nhau, chẳng hạn như 3. Để dễ dàng chứng minh điều này, chúng tôi sẽ sử dụng ứng dụng sơ khai sau đây để xử lý việc tạo vùng chứa của chúng tôi (một 4), tạo canvas pixmap, hiển thị nó trong vùng chứa và thêm vùng chứa vào cửa sổ chínhtrăn
Tại sao chúng ta sử dụng 4 để vẽ tiếp? Lưu tệp này vào một tệp và chạy tệp đó và bạn sẽ thấy như sau — một đường kẻ màu đen duy nhất bên trong khung cửa sổ — Một đường màu đen duy nhất trên canvasTất cả các bản vẽ diễn ra trong phương thức 8 — chúng tôi tạo một thể hiện 1, chuyển vào khung vẽ ( 00) và sau đó ra lệnh vẽ một đường. Cuối cùng, chúng tôi gọi 01 để đóng họa sĩ và áp dụng các thay đổiThông thường, bạn cũng cần gọi 02 để kích hoạt làm mới tiện ích, nhưng như chúng ta đang vẽ trước khi cửa sổ ứng dụng hiển thị, quá trình làm mới sẽ diễn raVẽ nguyên thủy 1 cung cấp một số lượng lớn các phương thức để vẽ các hình và đường trên bề mặt bitmap (trong 5. 12 có 192 1 phương pháp phi sự kiện cụ thể). Tin tốt là hầu hết trong số này là các phương thức quá tải đơn giản là các cách khác nhau để gọi cùng một phương thức cơ sởVí dụ: có 5 phương pháp 05 khác nhau, tất cả đều vẽ cùng một đường, nhưng khác nhau về cách xác định tọa độ của những gì cần vẽPhương phápMô tả 06Vẽ một thực thể 07 06Vẽ một thực thể 09 00Vẽ một đường thẳng giữa x1, y2 và x2, y2 ( 01) 02Vẽ một đường thẳng giữa p1 và p2 (cả hai đều là 03) 02Vẽ một đường thẳng giữa p1 và p2 (cả hai đều là 05)Nếu bạn đang tự hỏi sự khác biệt giữa 07 và 09 là gì, thì cái sau có tọa độ được chỉ định là 08. Điều này thuận tiện nếu bạn có các vị trí thả nổi do kết quả của các phép tính khác, nhưng nếu không thì không quá nhiềuBỏ qua các biến thể F, chúng ta có 3 cách duy nhất để vẽ một đường — với một đối tượng đường, với hai bộ tọa độ 09 hoặc với hai đối tượng 03. Khi bạn phát hiện ra rằng bản thân một 07 được định nghĩa là 22hoặc 23, bạn sẽ thấy rằng thực tế chúng hoàn toàn giống nhau. Các chữ ký cuộc gọi khác nhau chỉ đơn giản là có để thuận tiệnVới tọa độ x1, y1, x2, y2, hai đối tượng 03 sẽ được định nghĩa là 25 và 26Loại bỏ các bản trùng lặp, chúng tôi có các hoạt động vẽ sau — 27 , 28, 29, 00,_______105, 02, 03, 04, 05, 06, 07, 08 và 09. Để tránh bị choáng ngợp, trước tiên chúng ta sẽ tập trung vào các hình dạng và đường nét nguyên thủy và quay lại các thao tác phức tạp hơn khi chúng ta đã nắm rõ những điều cơ bảnĐối với mỗi ví dụ, hãy thay thế phương thức 8 trong ứng dụng sơ khai của bạn và chạy lại nó để xem đầu ravẽđiểmĐiều này vẽ một điểm hoặc pixel tại một điểm nhất định trên canvas. Mỗi cuộc gọi đến 04 vẽ một pixel. Thay thế mã 8 của bạn bằng mã sautrăn 3Nếu bạn chạy lại tệp, bạn sẽ thấy một cửa sổ, nhưng lần này chỉ có một dấu chấm duy nhất, màu đen ở giữa. Có lẽ bạn sẽ cần phải di chuyển cửa sổ xung quanh để phát hiện ra nó Vẽ một điểm (pixel) bằng QPainterĐó thực sự không phải là nhiều để xem xét. Để làm cho mọi thứ thú vị hơn, chúng ta có thể thay đổi màu sắc và kích thước của điểm mà chúng ta đang vẽ. Trong PyQt, màu sắc và độ dày của các đường được xác định bằng bút hoạt động trên QPainter. Bạn có thể thiết lập điều này bằng cách tạo một phiên bản 43 và áp dụng nótrăn
Điều này sẽ cho kết quả thú vị hơn một chút sau đây Một chấm đỏ lớnBạn có thể tự do thực hiện nhiều thao tác vẽ với 1 của mình cho đến khi họa sĩ kết thúc. Vẽ lên khung vẽ rất nhanh — ở đây chúng tôi vẽ ngẫu nhiên 10 nghìn điểmtrăn 0Các dấu chấm có chiều rộng 3 pixel và màu đen (bút mặc định) Bạn sẽ thường muốn cập nhật bút hiện tại trong khi vẽ — e. g. để vẽ nhiều điểm bằng các màu khác nhau trong khi vẫn giữ nguyên các đặc điểm khác (chiều rộng). Để thực hiện việc này mà không cần tạo lại phiên bản 43 mới mỗi lần, bạn có thể lấy bút hoạt động hiện tại từ 1 bằng cách sử dụng 47. Bạn cũng có thể áp dụng lại bút hiện có nhiều lần, thay đổi bút mỗi lầntrăn 0Sẽ tạo ra đầu ra sau - Mô hình ngẫu nhiên của 3 chấm chiều rộngChỉ có thể có một 43 hoạt động trên một 1 — bút hiện tạiĐó là mức độ phấn khích mà bạn có thể vẽ các chấm trên màn hình, vì vậy chúng ta sẽ chuyển sang xem xét một số thao tác vẽ khác vẽ đường thẳngChúng tôi đã vẽ một đường thẳng trên canvas ngay từ đầu để kiểm tra xem mọi thứ có hoạt động không. Nhưng những gì chúng tôi đã không thử là đặt bút để kiểm soát sự xuất hiện của đường kẻ trăn 2Trong ví dụ này, chúng tôi cũng đang sử dụng 03 để xác định hai điểm cần kết nối với một đường, thay vì chuyển các tham số 61 riêng lẻ — hãy nhớ rằng cả hai phương thức đều giống hệt nhau về mặt chức năngMột đường màu xanh đậmdrawRect, drawRects và drawRoundedRectTất cả các hàm này đều vẽ hình chữ nhật, được xác định bởi các tọa độ 62, 63 và một 64 và 65 của hình chữ nhật hoặc bởi các trường hợp 66 hoặc 67 cung cấp thông tin tương đươngtrăn 0Hình vuông chỉ là hình chữ nhật có cùng chiều rộng và chiều cao Vẽ hình chữ nhậtBạn cũng có thể thay thế nhiều lệnh gọi tới 07 bằng một lệnh gọi tới 08 chuyển qua nhiều đối tượng 66. Điều này sẽ tạo ra kết quả chính xác như nhautrăn 4Các hình dạng đã vẽ có thể được điền vào PyQt bằng cách đặt cọ họa sĩ đang hoạt động hiện tại, chuyển trong một phiên bản 81 thành 82. Ví dụ sau tô tất cả các hình chữ nhật bằng màu vàng có hoa văntrăn 6Hình chữ nhật đầyĐối với bút, chỉ có một bút vẽ hoạt động trên một họa sĩ nhất định, nhưng bạn có thể chuyển đổi giữa chúng hoặc thay đổi chúng trong khi vẽ. Có một số mẫu kiểu bàn chải có sẵn. Có thể bạn sẽ sử dụng 83 nhiều hơn bất kỳ cái nào khácBạn phải đặt kiểu để xem bất kỳ phần tô nào vì mặc định là 84Các phương thức 09 vẽ một hình chữ nhật, nhưng với các cạnh tròn, do đó, lấy thêm hai tham số cho bán kính x & y của các góctrăn 8Hình chữ nhật trònCó một tham số cuối cùng tùy chọn để chuyển đổi giữa bán kính hình elip x & y của các góc được xác định theo thuật ngữ pixel tuyệt đối 86 (mặc định) hoặc tương ứng với kích thước của hình chữ nhật (được truyền dưới dạng giá trị 0…100). Vượt qua 86 để kích hoạt tính năng nàyvẽEllipsePhương pháp vẽ nguyên thủy cuối cùng mà chúng ta sẽ xem xét bây giờ là 00 có thể được sử dụng để vẽ hình elip hoặc hình trònHình tròn chỉ là hình elip có chiều rộng và chiều cao bằng nhau trăn 30Trong ví dụ này, 00 đang lấy 4 tham số, với hai tham số đầu tiên là vị trí x & y của phía trên bên trái của hình chữ nhật mà hình elip sẽ được vẽ, trong khi hai tham số cuối cùng lần lượt là chiều rộng và chiều cao của hình chữ nhật đóVẽ hình elip với x, y, chiều rộng, chiều cao hoặc QRectBạn có thể đạt được điều tương tự bằng cách vượt qua một 66Có một chữ ký cuộc gọi khác lấy tâm của hình elip làm tham số đầu tiên, được cung cấp dưới dạng đối tượng 03 hoặc 05, sau đó là bán kính x và y. Ví dụ dưới đây cho thấy nó đang hoạt độngtrăn 31Vẽ hình elip bằng Điểm và bán kínhBạn có thể tô hình elip bằng cách đặt 81 giống như để tô hình chữ nhật, các tính năng tương tự cho kiểu dáng và màu sắc có sẵnChữCuối cùng, chúng ta sẽ xem qua các phương pháp vẽ văn bản 1. Để kiểm soát phông chữ hiện tại trên 1, bạn sử dụng 306 chuyển vào phiên bản 307. Với điều này, bạn có thể kiểm soát họ, trọng lượng và kích thước (trong số những thứ khác) của văn bản bạn viết. Tuy nhiên, màu sắc của văn bản vẫn được xác định bằng bút hiện tạitrăn 32Bạn cũng có thể chỉ định vị trí bằng 03 hoặc 05Chiều rộng của bút không ảnh hưởng đến sự xuất hiện của văn bản Ví dụ văn bản bitmap xin chào thế giớiNgoài ra còn có các phương pháp để vẽ văn bản trong một khu vực được chỉ định. Ở đây các tham số xác định vị trí x & y và chiều rộng & chiều cao của hộp giới hạn. Văn bản bên ngoài hộp này bị cắt bớt (ẩn). Các cờ tham số thứ 5 có thể được sử dụng để kiểm soát căn chỉnh văn bản trong hộp cùng với những thứ khác trăn 33Hộp giới hạn được cắt bớt trên drawTextBạn có toàn quyền kiểm soát việc hiển thị văn bản bằng cách đặt phông chữ hoạt động trên họa sĩ thông qua đối tượng 307. Kiểm tra tài liệu QFont để biết thêm thông tinHơn 10.000 nhà phát triển đã mua Tạo ứng dụng GUI bằng Python & Qt Thông tin thêm Nhận sách [[ giảm giá. discount_pc ]]% GIẢM GIÁ cho [[giảm giá. mô tả ]] với mã [[ giảm giá. coupon_code ]] Cũng có sẵn qua GumroadLeanpubAmazon Bìa mềm Một chút thú vị với QPainterĐiều đó hơi nặng nề, vì vậy hãy xả hơi và làm điều gì đó vui vẻ. Cho đến nay, chúng tôi đã lập trình xác định các hoạt động vẽ để thực hiện. Nhưng chúng tôi có thể dễ dàng vẽ theo phản hồi đầu vào của người dùng — ví dụ: cho phép người dùng viết nguệch ngoạc trên khung vẽ. Trong phần này, chúng ta sẽ sử dụng những gì đã học được cho đến nay và sử dụng nó để xây dựng một ứng dụng Paint cơ bản Chúng ta có thể bắt đầu với cùng một phác thảo ứng dụng đơn giản, thêm trình xử lý 311 vào lớp 312 thay cho phương thức vẽ của chúng ta. Ở đây, chúng tôi sẽ lấy vị trí hiện tại của chuột của người dùng và vẽ một điểm trên canvastrăn 34Tại sao không có sự kiện nhấp chuột? . Điều này có thể được định cấu hình bằng cách sử dụng phương thức 313 — đặt điều này thành 314 (mặc định là 315) sẽ theo dõi chuột liên tụcNếu bạn lưu cái này và chạy nó, bạn sẽ có thể di chuột qua màn hình và nhấp để vẽ các điểm riêng lẻ. Nó sẽ trông giống như thế này - Vẽ các điểm mouseMoveEvent riêng lẻVấn đề ở đây là khi bạn di chuyển chuột xung quanh một cách nhanh chóng, nó thực sự nhảy giữa các vị trí trên màn hình, thay vì di chuyển trơn tru từ vị trí này sang vị trí khác. 311 được kích hoạt cho từng vị trí có chuột, nhưng điều đó không đủ để vẽ một đường liên tục, trừ khi bạn di chuyển rất chậmGiải pháp cho vấn đề này là vẽ các đường thay vì các điểm. Trên mỗi sự kiện, chúng tôi chỉ cần vẽ một đường từ vị trí của chúng tôi (trước đây là 317 và 318) đến vị trí hiện tại của chúng tôi (hiện tại là 317 và 318). Chúng tôi có thể làm điều này bằng cách tự mình theo dõi 321 và 322Chúng tôi cũng cần phải quên vị trí cuối cùng khi nhả chuột hoặc chúng tôi sẽ bắt đầu vẽ lại từ vị trí đó sau khi di chuyển chuột trên trang — i. e. chúng tôi sẽ không thể phá vỡ dòng trăn 35Nếu bạn chạy cái này, bạn sẽ có thể viết nguệch ngoạc trên màn hình như bạn mong đợi Vẽ bằng chuột, sử dụng một đường liên tụcNó vẫn còn hơi buồn tẻ, vì vậy hãy thêm một bảng màu đơn giản để cho phép chúng ta thay đổi màu bút Điều này đòi hỏi một chút kiến trúc lại. Cho đến nay chúng tôi đã sử dụng 311 trên 324. Khi chúng tôi chỉ có một tiện ích duy nhất trong cửa sổ thì điều này không sao — miễn là bạn không thay đổi kích thước cửa sổ lớn hơn tiện ích (bạn đã thử chưa?), tọa độ của vùng chứa và tiện ích con lồng nhau thẳng hàng. Tuy nhiên, nếu chúng tôi thêm các tiện ích con khác vào bố cục thì điều này sẽ không giữ được — tọa độ của 4 sẽ bị lệch khỏi cửa sổ và chúng tôi sẽ vẽ sai vị tríĐiều này có thể dễ dàng khắc phục bằng cách di chuyển bộ xử lý chuột lên chính 4— tọa độ sự kiện của nó luôn tương đối với chính nó. Điều này chúng tôi kết thúc dưới dạng một đối tượng 327 tùy chỉnh, xử lý việc tạo bề mặt pixmap, thiết lập các vị trí x & y và giữ màu bút hiện tại (được đặt thành màu đen theo mặc định) 327 khép kín này là một bề mặt có thể kéo thả vào mà bạn có thể sử dụng trong các ứng dụng của riêng mìnhtrăn 36Đối với lựa chọn màu sắc, chúng tôi sẽ xây dựng một tiện ích con tùy chỉnh, dựa trên 329. Tiện ích con này chấp nhận tham số 330 có thể là phiên bản 331 hoặc tên màu ('đỏ', 'đen') hoặc giá trị hex. Màu này được đặt trên nền của tiện ích để dễ nhận dạng. Chúng tôi có thể sử dụng tín hiệu tiêu chuẩn 332 để kết nối nó với bất kỳ hành động nàotrăn 37Với hai phần mới được xác định, chúng ta chỉ cần lặp lại danh sách màu của mình, tạo một 333 truyền màu, kết nối tín hiệu được nhấn của nó với trình xử lý 334 trên khung vẽ (gián tiếp qua một 335 để truyền dữ liệu màu bổ sung) và trăn 38Điều này sẽ cung cấp cho bạn một ứng dụng sơn nhiều màu hoạt động đầy đủ, nơi bạn có thể vẽ các đường trên canvas và chọn màu từ bảng màu Thật không may, nó không làm cho bạn trở thành một nghệ sĩ giỏiXịt nướcĐể có một chút thú vị cuối cùng, bạn có thể tắt 311 với phần sau để vẽ bằng hiệu ứng "bình xịt" thay vì đường kẻ. Điều này được mô phỏng bằng cách sử dụng 337 để tạo ra một loạt các dấu chấm được phân phối bình thường xung quanh vị trí chuột hiện tại mà chúng tôi vẽ bằng 04trăn 39Xác định các biến 339 và 340 ở đầu tệp của bạn và nhập mô-đun thư viện chuẩn 341. Hình ảnh bên dưới hiển thị hành vi phun khi sử dụng các cài đặt sautrăn 0Đối với lon xịt, chúng ta không cần theo dõi vị trí trước đó, vì chúng ta luôn xịt xung quanh điểm hiện tại Nếu muốn thử thách, bạn có thể thử thêm một nút bổ sung để chuyển đổi giữa chế độ vẽ và phun hoặc đầu vào để xác định đường kính chổi/phun Để biết chương trình vẽ đầy đủ chức năng được viết bằng PyQt5, hãy xem Ứng dụng 15 phút "Piecasso" của tôi Phần giới thiệu này sẽ cho bạn ý tưởng tốt về những gì bạn có thể làm với 1. Như đã mô tả, hệ thống này là cơ sở của tất cả các bản vẽ phụ tùng. Nếu bạn muốn tìm hiểu thêm, hãy xem phương thức 343 của widget, phương thức này nhận một phiên bản 1, để cho phép widget tự vẽ. Các phương pháp tương tự bạn đã học ở đây có thể được sử dụng trong 343 để vẽ một số tiện ích tùy chỉnh cơ bản. Chúng tôi sẽ mở rộng về điều này trong hướng dẫn tiếp theo |