我有一个用glade ver.38和PyGObject 3.38编写的.glade
文件。现在我在Ubuntu 21.10上使用PyGObject 3.40。所以,我用gtk4-builder-tool
将我的glade从gtk3转换为gtk4,但我得到了一个错误gi.repository.GLib.Error: gtk-builder-error-quark: No function named btnProcess_clicked_cb. (14)
Glade文件
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<requires lib="gtk" version="4.0"/>
<object class="GtkWindow" id="graywindow">
<signal name="destroy" handler="graywindow_destroy_cb" swapped="no"/>
<property name="child">
<object class="GtkBox">
<property name="orientation">vertical</property>
<child>
<object class="GtkLabel">
<property name="label" translatable="yes">1811
Jq
IC</property>
<property name="width-chars">0</property>
<attributes>
<attribute name="font-desc" value="Sans Bold 14"></attribute>
<attribute name="style" value="normal"></attribute>
</attributes>
</object>
</child>
<child>
<object class="GtkBox">
<property name="homogeneous">1</property>
<child>
<object class="GtkLabel">
<property name="label" translatable="yes">Image Ori</property>
</object>
</child>
</object>
</child>
<child>
<object class="GtkBox">
<property name="homogeneous">1</property>
<child>
<object class="GtkImage" id="imgOri">
<property name="icon-name">image</property>
</object>
</child>
</object>
</child>
<child>
<object class="GtkBox">
<property name="homogeneous">1</property>
<child>
<object class="GtkLabel">
<property name="label" translatable="yes">Prewitt</property>
</object>
</child>
<child>
<object class="GtkLabel">
<property name="label" translatable="yes">Global Threshold
</property>
</object>
</child>
<child>
<object class="GtkLabel">
<property name="label" translatable="yes">Otsu</property>
</object>
</child>
</object>
</child>
<child>
<object class="GtkBox">
<property name="homogeneous">1</property>
<child>
<object class="GtkImage" id="imgGray">
<property name="icon-name">image</property>
</object>
</child>
<child>
<object class="GtkImage" id="imgGT">
<property name="icon-name">image</property>
</object>
</child>
<child>
<object class="GtkImage" id="imgO">
<property name="icon-name">image</property>
</object>
</child>
</object>
</child>
<child>
<object class="GtkBox">
<property name="homogeneous">1</property>
<child>
<object class="GtkButton" id="btnProcess">
<property name="label" translatable="yes">Process</property>
<property name="focusable">1</property>
<property name="receives-default">1</property>
<signal name="clicked" handler="btnProcess_clicked_cb" swapped="no"/>
</object>
</child>
</object>
</child>
<child>
<object class="GtkBox">
<property name="homogeneous">1</property>
<child>
<object class="GtkEntry">
<property name="focusable">1</property>
</object>
</child>
<child>
<object class="GtkButton" id="btnBrowse">
<property name="label" translatable="yes">browse</property>
<property name="focusable">1</property>
<property name="receives-default">1</property>
<signal name="clicked" handler="btnBrowse_clicked_cb" swapped="no"/>
</object>
</child>
</object>
</child>
</object>
</property>
</object>
</interface>
Python文件
from gi.repository import Gtk
import numpy as np
import cv2
import gi
from matplotlib import pyplot as plt
import sys
gi.require_version('Gtk', '4.0')
class grayProcess:
def graywindow_destroy_cb(self, object, data=None):
Gtk.main_quit()
def btnBrowse_clicked_cb(self, object, data=None):
self.dialog = Gtk.FileChooserDialog(
'Please Choose a File',
None,
Gtk.FileChooserAction.OPEN,
(Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL, Gtk.STOCK_OPEN, Gtk.ResponseType.OK))
self.response = self.dialog.run()
global url
if self.response == Gtk.ResponseType.OK:
self.search = self.builder.get_object('txtSearch')
imgOri = self.builder.get_object('imgOri')
url = self.dialog.get_filename()
self.search.set_text(str(url))
imgOri.set_from_file(url)
elif self.response == Gtk.ResponseType.cancel:
print('Cancel Clicked')
self.dialog.destroy()
def btnProcess_clicked_cb(self, object, data=None):
self.img = cv2.imread(url)
imgGrey = self.builder.get_object('imgGray')
# Prewitt Start
self.gray = cv2.cvtColor(self.img, cv2.COLOR_BGR2GRAY)
img_gaussian = cv2.GaussianBlur(self.gray, (3, 3), 0)
kernelx = np.array([[1, 1, 1], [0, 0, 0], [-1, -1, -1]])
kernely = np.array([[-1, 0, 1], [-1, 0, 1], [-1, 0, 1]])
img_prewittx = cv2.filter2D(img_gaussian, -1, kernelx)
img_prewitty = cv2.filter2D(img_gaussian, -1, kernely)
cv2.imwrite('image/prewitt.jpg', img_prewittx + img_prewitty)
imgGrey.set_from_file('image/prewitt.jpg')
# Prewitt End
# Global Threshold Start
self.img = cv2.imread(url, 0)
imgGt = self.builder.get_object('imgGT')
dimensao = self.img.shape
img = cv2.medianBlur(self.img, 5)
ret, th1 = cv2.threshold(img, 127, 255, cv2.THRESH_BINARY)
value = cv2.countNonZero(th1)
titles = ['Original Image', 'Global Thresholding (v = 127)']
images = [img, th1]
for i in range(len(images)):
plt.subplot(2, 2, i+1), plt.imshow(images[i], 'gray')
plt.title(titles[i])
plt.xticks([]), plt.yticks([])
cv2.imwrite('image/Global Threshold.jpg', th1)
imgGt.set_from_file('image/Global Threshold.jpg')
# Global Threshold End
# Start Otsu
self.img = cv2.imread(url, 0)
imgo = self.builder.get_object('imgO')
ret, thresh2 = cv2.threshold(self.img, 127, 255, cv2.THRESH_BINARY_INV)
titles = ['Original Image', 'BINARY',
'BINARY_INV', 'TRUNC', 'TOZERO', 'TOZERO_INV']
images = [self.img, thresh2]
for i in range(0, 6):
plt.subplot(2, 3, i+1), plt.imshow(images[i], 'gray')
plt.title(titles[i])
plt.xticks([]), plt.yticks([])
cv2.imwrite('image/otsu.jpg', thresh2)
imgo.set_from_file('image/otsu.jpg')
# Otsu End
def __init__(self):
self.gladefile = ('uts_cv.glade')
self.builder = Gtk.Builder()
self.builder.add_from_file(self.gladefile)
self.builder.connect_signals(self)
self.window = self.builder.get_object('graywindow')
self.window.show()
if __name__ == '__main__':
main = grayProcess()
Gtk.main()
根据gtk4文档,https://docs.gtk.org/gtk4/migrating-3to4.html#adapt-到gtkbuilder api更改
gtk_builder_connect_signals()
已不存在。相反,信号总是自动连接的。如果需要将用户数据添加到信号中,则必须调用gtk_builder_set_current_object()
。一个重要的警告是,您必须在加载任何XML之前执行此操作。这意味着,如果需要使用gtk_builder_set_current_object()
,则不能再使用gtk_builder_new_from_file()
、gtk_builder_new_from_resource()
或gtk_builder_new_from_string()
。相反,您必须使用普通的gtk_builder_new()
,然后调用gtk_builder_set_current_object()
,然后使用gtk_builder_add_from_file()
、gtk_builder_add_from_resource()
或gtk_builder_add_from_string()
加载XML。您必须检查返回值是否失败,如果出现问题,则使用g_error()
手动中止。
现在使用信号的简单方法,imo是Gtk.Template
,您可以在这里查看文档,https://pygobject.readthedocs.io/en/latest/guide/gtk_template.html