android开发中 linearlayout中如何将子控件动态插入指定的位置

android开发中 linearlayout中如何将子控件动态插入指定的位置,第1张

LinearLayout是线性布局控件,它包含的子控件将以横向或竖向的方式排列,按照相对位置来排列所有的widgets或者其他的containers,超过边界时,某些控件将缺失或消失。因

此一个垂直列表的每一行只会有一个widget或者是container,而不管他们有多宽,而一个水平列表将会只有一个行高(高度为最高子控件的高度加上边框高度)。LinearLayout保持其所包含的widget或者是container之间的间隔以及互相对齐(相对一个控件的右对齐、中间对齐或者左对齐)

1 常用的xml属性

android:baselineAligned:是否允许用户调整它内容的基线。

android:baselineAlignedChildIndex:当一个线性布局与另一个布局是按基线对齐的一部分,它可以指定其内容的基线对齐方式。

android:gravity:指定如何在该对象中放置此对象的内容(x/y坐标值)。 android:orientation:设置它内容的对其方向(横向/竖向)。

gravity 这个英文单词是重心的意思,在这里就表示停靠位置的意思。

android:layout_gravity 和 android:gravity 的区别

从名字上可以看到,android:gravity是对元素本身说的,元素本身的文本显示在什么地方靠着换个属性设置,不过不设置默认是在左侧的。

android:layout_gravity是相对与它的父元素说的,说明元素显示在父元素的什么位置。 比如说button: android:layout_gravity 表示按钮在界面上的位置。 android:gravity表示button上的字在button上的位置。

可选值

这两个属性可选的值有:top、bottom、left、right、center_vertical、fill_vertical、center_horizontal、fill_horizontal、center、fill、clip_vertical。

而且这些属性是可以多选的,用“|”分开。 默认这个的值是:GravityLEFT

2 对于LinearLayout何时生效的问题

当 android:orientation="vertical" 时, 只有水平方向的设置才起作用,垂直方向的设置不起作用。即:left,right,center_horizontal 是生效的。 当 android:orientation="horizontal" 时, 只有垂直方向的设置才起作用,水平方向的设置不起作用。即:top,bottom,center_vertical 是生效的。

3LinearLayout还支持为其包含的widget或者是container指定填充权值。好处就是允许其包含的widget或者是container可以填充屏幕上的剩余空间。这也避免了在一个大屏幕中,一串widgets或者是containers挤成一堆的情况,而是允许他们放大填充空白。剩余的空间会按这些widgets或者是containers指定的权值比例分配屏幕。默认的 weight 值为0,表示按照widgets或者是containers实际大小来显示,若高于0的值,则将Container剩余可用空间分割,分割大小具体取决于每一个widget或者是container的layout_weight及该权值在所有widgets或者是containers中的比例。例如,如果有三个文本框,其中两个指定的权值为1,那么,这两个文本框将等比例地放大,并填满剩余的空间,而第三个文本框不会放大,按实际大小来显示。如果前两个文本框的取值一个为2,一个为1,显示第三个文本框后剩余的空间的2/3给权值为2的,1/3大小给权值为1的。也就是权值越大,重要度越大。

如果LinearLayout包含子LinearLayout,子LinearLayout之间的权值越大的,重要度则越小。如果有LinearLayout A包含LinearLayout C,D,C的权值为2,D的权值为1,则屏幕的2/3空间分给权值为1的D,1/3分给权值为2的C。在LinearLayout嵌套的情况下,子LinearLayout必须要设置权值,否则默认的情况是未设置权值的子LinearLayout占据整个屏幕

安装Pyinstaller

1

按照习惯,我们使用pip来安装模块。我们一直以来强调,要用最偷懒的方法。写代码的人尤其如此。人生苦短,你要偷懒~

0Python | 如何用pip安装模块和包

2

虽然部分第三方模块有独立的exe安装包,不过使用pip安装的另一个好处是,pip会自动安装这个第三方包需要的依赖模块(比如,这里帮我们下载了pypiwin32这个依赖)。这不,又省心不少。

3

安装完成后,我们可以在如下路径找到Pyinstaller应用程序。

wxWidgets是一个跨平台的软件开发包。它诞生于1992年,最初的名子是wxWindows,但由于Microsoft的抗议,在2004年改名为wxWidgets。它最初是被设计成跨平台的GUI软件开发包,但后来随着越来越多的人参与进来,为wxWidgets加入了许多非GUI的功能,如多线程(MultiThread)、网络(Network)等。并且从最初的只支持C++语言,逐渐发展成为支持数种语言(如Python、Perl、C#、Basic等)。因此,现在的wxWidgets已经不再是单纯的跨平台的GUI软件开发包,而是一个可以支持多种 *** 作系统平台的能够在多种语言中使用的通用跨平台软件开发包。

由于wxWidgets最开始是为C++而设计的,因此,本文主要讨论了wxWidgets在C++中的使用。

为什么选择wxWidgets?

目前支持C++的软件开发包非常多,比较有名的除了wxWidgets外,还有一些其它的软件开发包,如MFC、QT、ACE等。即然有这么多开发包,那么我们为什么要使用wxWidgets呢?在给出答案之前,让我们首先来看一看上述的三种软件开发包的特性。

1       MFC

MFC是Microsoft提供的软件开发包。MFC虽然十分强大,但它只能运行在Windows下运行。而且它是收费的。

2  QT

QT是由Trolltech 公司开发的一套跨平台软件开发包。它和wxWidgets类似,但是QT只在linux下免费,而在Windows或Unix下使用QT要向Trolltech公司支付版权费。

3  ACE

ACE虽然是免费开源的,但是它没有提供GUI功能。

  从以上三个软件开发包可以看出,它们虽然有各自的优势,但是它们或多或少地都会使开发受到限制。而使用wxWidgets将不会有以上所述的问题。wxWidgets和MFC、QT、 ACE的特性对比如表1所示。

注:其中免费中的“是/否”代表QT在linux平台上的Free Edition是免费的,而在windows和unix下使用QT是收费的。而开源中的“是/否”代表QT有一个基于GPL的开源版本,但要进行商业开发,需要使用它的商业版本。

使用wxWidgets编写程序

学习一种编程语言的最好方法就是用它去编写程序,学习wxWidgets也不例外。由于wxWidgets的主要功能是实现跨平台的GUI,因此,本文主要从GUI入手,讨论wxWidgets在C++中如何编写跨平台的应用程序

1  应用程序类的建立

使用wxWidgets建立系统需要一个类来描述整个应用程序。这个类必须从wxApp类继承。

class MyApp : public wxApp   //应用程序类

{

public:

  virtual bool OnInit(); // 在应用程序启动时调用,如果返回false,退出应用程序

};

这个类只覆盖了wxApp的一个虚方法OnInit。可以用这个方法在程序启动时做一些验证,如果验证失败,可以通过返回false退出应用程序。当然,由于这个函数是应用程序的入口点,所以建立主窗体的工作要在这个函数中完成。

2 建立窗体类

  wxWidgets中关于窗体的类很多,如果要建立一般窗体的话,可以从wxFrame继承。

class MyFrame : public wxFrame //窗体类

{

public:

  MyFrame(const wxString& title); // 窗体的构造函数

};

3 向窗体中加入控件

  在本文中向这个窗体加入了一个菜单条(Menu Bar)、一个状态条、一个Panel和一个按钮。一般我们会在主窗体的构造函数中加入这些控件。

MyFrame::MyFrame(const wxString& title) : wxFrame(NULL, wxID_ANY, title)

{

  wxMenu fileMenu = new wxMenu;  // 建立“文件”菜单

  wxMenu helpMenu = new wxMenu; // 建立“帮助”菜单

  // 向菜单中添加子项

  helpMenu->Append(wxID_ABOUT, _T("关于"tF1"), _T("显示关于对话框"));

  fileMenu->Append(wxID_EXIT, _T("退出"tAlt-X"), _T("退出应用程序"));

  wxMenuBar menuBar = new wxMenuBar();  // 建立一个菜单条

  menuBar->Append(fileMenu, _T("文件"));  //将“文件”菜单加入到菜单条

  menuBar->Append(helpMenu, _T("帮助"));  //将“帮助”菜单加入到菜单条

  SetMenuBar(menuBar);  //将菜单条放到窗体上

  wxPanel panel = new wxPanel(this);   //建立一个Panel

  wxButton button = new wxButton(panel, wxID_ABOUT, "关于", wxPoint(20, 20), wxSize(50, 30));  //建立一个Button

  CreateStatusBar(2);  //建立一个两栏的状态栏

  SetStatusText(_T("欢迎使用wxWidgets!"));  //设置状态栏的文本

  在数组sample_xpm中描述了sampleico的属性和图标本身。如X代表红色; o代表**等。然后在源程序中通过include “samplexpm”引用这个资源文件。要想从这个资源文件中装载图标。可使用SetIcon(wxICON(sample)); wxICON读取资源文件,而SetIcon将这个图标设置为frame的标题栏图标。要想将ico文件转换为这种资源文件,可使用一个免费软件XnView进行转换。

5 显示主窗体

  显示主窗体非常简单,只需要将上面建立的MyFrame类实例化,并调用wxFrame的Show方法显示即可。这些代码可以写在MyApp类的OnInit方法中。

bool MyApp::OnInit()

{

  //建立MyFrame类的实例

  MyFrame frame = new MyFrame(_T("第一个wxWidgets程序"));

  frame->Show(true);  //显示主窗体

  return true;  //必须返回true,否则应用程序将退出

}

在以上代码中Show方法有一个参数,如果为true,则以模式窗口的形式显示,否则以非模式窗口的形式显示。

6 向窗体中加入事件

到目前为止,这个程序的界面已经完成了,但还未响应任何事件,下面就详细阐述如何向这个应用程序中加入事件代码。

  对于事件来说,一般都会由两部分组成。

(1)调用事件部分

当程序发生某个动作时,如点击按钮;选中某个控件,可能需要执行一段代码。而这段代码一般是由系统负责调用的,也就是说系统通过事件函数指针调用相应的代码。

(2)事件函数本身

  事件函数与普通函数一样,只不过它是在发生了事件之后,由系统调用的。

在wxWidgets中是通过事件哈希表(Event Hash Table)来进行事件处理的,即将相应的事件函数指针保存在一个哈希表中,然后当事件发生时,从这个哈希表中找到相应的事件函数指针,然后通过函数指针调用函数。在使用事件哈希表之前,必须定义它。由于定义哈希表非常复杂,而且每个需要处理事件的类都需要同样的代码,因此,wxWidgets为此定义了一个宏DECLARE_EVENT_TABLE()来定义哈希表。可将这个宏写在MyFrame类的任何位置。它相当于将以下语句放到了MyFrame类中。

  private:

     static const wxEventTableEntry sm_eventTableEntries[];

  protected:

      static const wxEventTable  sm_eventTable;

      virtual const wxEventTable  GetEventTable() const;

      static wxEventHashTable  sm_eventHashTable;

      virtual wxEventHashTable&  GetEventHashTable() const;

其中静态数组变量sm_eventTableEntries保存了MyFrame类中的所有的事件信息。

上面的代码声明了处理事件哈希表的一些方法,即然声明了,就得实现。由于实现代码也都一样,因此,wxWidgets也为实现这些方法定义了一组宏。实现这些方法的宏如下所示。

BEGIN_EVENT_TABLE(MyFrame, wxFrame)

  EVT_MENU(wxID_EXIT,  MyFrame::OnQuit)

  EVT_MENU(wxID_ABOUT, MyFrame::OnAbout)

  EVT_BUTTON(wxID_ABOUT, MyFrame::OnAbout)

END_EVENT_TABLE()

  其中BEGIN_EVENT_TABLE(…)实现了上面定义的方法,以及初始化了静态变量sm_eventTable。后面两个EVT_MENU和一个EVT_BUTTON宏初始化了静态变量sm_eventTableEntries,即将这两个事件函数的指针(button和about菜单使用一个事件函数OnAbout)和控件ID保存在sm_eventTableEntries中,最后的END_EVENT_TABLE()宏做为一个空的事件函数指针赋给了sm_eventTableEntries,这有些象C语言中处理字符串,将最后一个字符赋为’"0’,这样就可以知道哪是结尾了。

  向窗体中加入事件的最后一步是声明和实现事件函数。在本例中声明了两个事件函数。

void OnQuit(wxCommandEvent& event);

void OnAbout(wxCommandEvent& event);

可以将这两个函数声明放到MyFrame中的任何位置。下面是它们的实现代码。

void MyFrame::OnQuit(wxCommandEvent& WXUNUSED(event))

{

  Close(true);

}

void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event))

{

  wxString msg;

  msgPrintf( _T("这是一个关于对话框的例子"n")

              _T("欢迎使用 %s"), wxVERSION_STRING);

  wxMessageBox(msg, _T("¹关于"), wxOK | wxICON_INFORMATION, this);

}

其中OnQuit函数调用Close(true)关闭MyFrame,由于MyFrame是主窗体,因此,在MyFrame关闭后,应用程序也随之关闭了。OnAbout使用wxMessageBox函数d出一个信息对话框。

7  运行程序

到目前为止,这个程序的代码已经基本完成了,但是在前面曾说过,MyApp中的OnInit方法在应用程序启动时执行,那么是谁调用了OnInit方法呢?答案当然是wxWidgets。wxWidgets为了调用这个方法,提供了一个宏IMPLEMENT_APP(…),这个宏有一个参数,需要将MyApp做为参数传入。即IMPLEMENT_APP(MyApp)。这个宏相当于一个WinMain函数(和控制台程序的main函数类似),即在WinMain函数中调用了MyApp中的OnInit函数。在加入这个宏后,就可使用一个C++编译器将以上的源程序编译生成exe文件了。

在制作eclipse插件的时候,时常需要对已经存在的视图做一些扩展,例如在project explorer中增加一个右键菜单,或者需要获取outline中当前选中项,等等。而这些 *** 作的前提,是获取这些视图的id,然后通过获取视图的语句获取到视图,并进行下一步 *** 作。

例如:如果是在view中:

IViewPartpart=getViewSite()getPage()findView("orgeclipseuiviewsContentOutline");

如果是在action中:

IViewPartpart=PlugingetDefault()getWorkbench()getActiveWorkbenchWindow()getActivePage()findView("orgeclipseuiviewsContentOutline");

可见获取到视图的id是很重要的。如何获取id呢,有很多方法,我觉得比较常用的是以下两种:

1通过手动查找目标视图所在的插件的pluginxml中对改视图的定义,获得视图id。

描述:我觉得这是最保险的办法,因为所有的视图都必定有一个pluginxml定义,但是找到这个pluginxml还是需要一些 *** 作,可能会耗费一些时间。

步骤:

a点击“工具栏”->“Search”->“Search”,或者热键“ctrl+h”。选“ Plugin Search”。

bSearch for 选"Extention Point",Limit to 选“references”,External Scope 选“Enabled Plug-ins only”。

c下面的scope选“Worksapaces”。

d上面的Search String框填入我们要搜索的插件的扩展点的名字,这里我们要找视图插件,所以填入:orgeclipseuiviews

e点击search以后,在底部Search视图内列出很多搜索结果,任意选中一个,双击,可以看到editor内打开了该pluginxml,选中编辑器底部的Extentions,用图形化的方式来查看会更快捷。

f可以看到该插件使用的扩展点已经以列表的形式列出,我们查找的orgeclipseuiviews扩展点也已经选中,展开选中的扩展点,可以看到它实现了哪些view,点击某一个,可以在页面右边看到该视图的详细信息,第一项即是视图的id。

我们无法知道目标视图在搜索结果中的哪个plugin中,所以可能会耗费一些时间,建议在查看搜索结果时,通过对视图的分类分析,确定一个大概范围再进行查看。

同时,用这种方法也可以查找其他扩展点的实现插件。

2通过代码直接读出该视图的id。

描述:通过这种方法,可以直接用鼠标点击某个你想知道的视图,控制台会打印出该视图的id和所属插件的id。

步骤:

a通过插件向导新建一个插件,并使用Available Templates中的Plugin with a view模板,点finish。

b对自动创建的SampleView代码进行修改,修改结果如下。其中主要步骤有三个:实现IPartListener2接口,编写isActivePart()方法,调用isActivePart()方法。

packagecomraullearnsampleviewviews;

importorgeclipseswtwidgetsComposite;

importorgeclipseuipart;

importorgeclipsejfaceviewers;

importorgeclipseswtgraphicsImage;

importorgeclipsejfaceaction;

importorgeclipsejfacedialogsMessageDialog;

importorgeclipseui;

importorgeclipseswtwidgetsMenu;

importorgeclipseswtSWT;

importcomraullearnsampleviewActivator;

/

Thissampleclassdemonstrateshowtoplug-inanew

workbenchviewTheviewshowsdataobtainedfromthe

modelThesamplecreatesadummymodelonthefly,

butarealimplementationwouldconnecttothemodel

availableeitherinthisoranotherplug-in(egtheworkspace)

Theviewisconnectedtothemodelusingacontentprovider

<p>

Theviewusesalabelprovidertodefinehowmodel

objectsshouldbepresentedintheviewEach

viewcanpresentthesamemodelobjectsusing

differentlabelsandicons,ifneededAlternatively,

asinglelabelprovidercanbesharedbetweenviews

inordertoensurethatobjectsofthesametypeare

presentedinthesamewayeverywhere

<p>

/

publicclassSampleViewextendsViewPartimplementsIPartListener2{

privateTableViewerviewer;

privateActionaction1;

privateActionaction2;

privateActiondoubleClickAction;

/

Thecontentproviderclassisresponsiblefor

providingobjectstotheviewItcanwrap

existingobjectsinadaptersorsimplyreturn

objectsas-isTheseobjectsmaybesensitive

tothecurrentinputoftheview,orignore

itandalwaysshowthesamecontent

(likeTaskList,forexample)

/

classViewContentProviderimplementsIStructuredContentProvider{

publicvoidinputChanged(Viewerv,ObjectoldInput,ObjectnewInput){

}

publicvoiddispose(){

}

publicObject[]getElements(Objectparent){

returnnewString[]{"One","Two","Three"};

}

}

classViewLabelProviderextendsLabelProviderimplementsITableLabelProvider{

publicStringgetColumnText(Objectobj,intindex){

returngetText(obj);

}

publicImagegetColumnImage(Objectobj,intindex){

returngetImage(obj);

}

publicImagegetImage(Objectobj){

returnPlatformUIgetWorkbench()

getSharedImages()getImage(ISharedImagesIMG_OBJ_ELEMENT);

}

}

classNameSorterextendsViewerSorter{

}

/

Theconstructor

/

publicSampleView(){

ActivatorgetDefault()getWorkbench()getActiveWorkbenchWindow()

getActivePage()addPartListener(this);

}

@Override

publicvoiddispose(){

//TODOAuto-generatedmethodstub

ActivatorgetDefault()getWorkbench()getActiveWorkbenchWindow()

getActivePage()removePartListener(this);

superdispose();

}

/

Thisisacallbackthatwillallowus

tocreatetheviewerandinitializeit

/

publicvoidcreatePartControl(Compositeparent){

viewer=newTableViewer(parent,SWTMULTI|SWTH_SCROLL|SWTV_SCROLL);

viewersetContentProvider(newViewContentProvider());

viewersetLabelProvider(newViewLabelProvider());

viewersetSorter(newNameSorter());

viewersetInput(getViewSite());

makeActions();

hookContextMenu();

hookDoubleClickAction();

contributeToActionBars();

}

privatevoidhookContextMenu(){

MenuManagermenuMgr=newMenuManager("#PopupMenu");

menuMgrsetRemoveAllWhenShown(true);

menuMgraddMenuListener(newIMenuListener(){

publicvoidmenuAboutToShow(IMenuManagermanager){

SampleViewthisfillContextMenu(manager);

}

});

Menumenu=menuMgrcreateContextMenu(viewergetControl());

viewergetControl()setMenu(menu);

getSite()registerContextMenu(menuMgr,viewer);

}

privatevoidcontributeToActionBars(){

IActionBarsbars=getViewSite()getActionBars();

fillLocalPullDown(barsgetMenuManager());

fillLocalToolBar(barsgetToolBarManager());

}

privatevoidfillLocalPullDown(IMenuManagermanager){

manageradd(action1);

manageradd(newSeparator());

manageradd(action2);

}

privatevoidfillContextMenu(IMenuManagermanager){

manageradd(action1);

manageradd(action2);

//Otherplug-inscancontributethereactionshere

manageradd(newSeparator(IWorkbenchActionConstantsMB_ADDITIONS));

}

privatevoidfillLocalToolBar(IToolBarManagermanager){

manageradd(action1);

manageradd(action2);

}

@Override

publicvoidpartBroughtToTop(IWorkbenchPartReferencepartRef){

//TODOAuto-generatedmethodstub

}

@Override

publicvoidpartClosed(IWorkbenchPartReferencepartRef){

//TODOAuto-generatedmethodstub

}

@Override

publicvoidpartDeactivated(IWorkbenchPartReferencepartRef){

//TODOAuto-generatedmethodstub

}

@Override

publicvoidpartHidden(IWorkbenchPartReferencepartRef){

//TODOAuto-generatedmethodstub

}

@Override

publicvoidpartInputChanged(IWorkbenchPartReferencepartRef){

//TODOAuto-generatedmethodstub

}

@Override

publicvoidpartOpened(IWorkbenchPartReferencepartRef){

//TODOAuto-generatedmethodstub

}

privatevoidisActivePart(){

IWorkbenchPartpart=getViewSite()getPage()getActivePart();

//returnpart!=null&&partequals(this);

Systemoutprintln(partgetSite()getId());

partgetSite()getPluginId();

}

}

然后调插件,在运行环境中调出该视图,接着当你用鼠标点击你想知道的视图时,在开发环境中的控制台,就会打印出该视图的id以及所属插件的id。

from PyQt5QtCore import 

from PyQt5QtGui import 

from PyQt5QtWidgets import 

from PyQt5QtWebEngineWidgets import 

import sys

class MainWindow(QMainWindow):

    def __init__(self ):

        super(QMainWindow, self)__init__()

        selfsetWindowTitle('QWebView打开网页例子')

        selfsetGeometry(5, 30, 1355, 730)

        #selfbrowser = QWebEngineView()

        #1 加载html代码

        selfbrowser = QWebEngineView()

        selfbrowsersetHtml('''

        <!DOCTYPE html>

        <html>

            <head>

                <meta charset="UTF-8">

                <title></title>

            </head>

            <body>

                <h1>Hello PyQt5</h1>

                <h1>Hello PyQt5</h1>

                <h1>hello PyQt5</h1>

                <h1>hello PyQt5</h1>

                <h1>hello PyQt5</h1>

                <h1>Hello PyQt5</h1>

                

            </body>

        </html>

        '''

        )

        

        selfsetCentralWidget(selfbrowser)

if __name__ == '__main__':

    app = QApplication(sysargv)

    

    win = MainWindow()

    winshow()

    sysexit(appexec_())

您好,您可以下载下来进行查看的,如果您的系统是64位的,那么直接双击qt5webenginecoredl文件,然后选择打开方式-exe即可进行解决。下载网址:如果您的系统是32位的,那么直接双击qt5webenginecoredl文件,然后选择打开方式-zip压缩文件即可进行解决。下载网址:如果您的系统是WIN7的系统,那么直接双击qt5webenginecoredl文件,然后选择解压到当前文件夹,然后双击qt5webenginecoredl文件即可进行解决。下载网址:如果您在上面的方法中没能解决您的问题,那么可以直接重新安装qt5webenginecoredl,重新下载安装后重新进行打开即可。

以上就是关于android开发中 linearlayout中如何将子控件动态插入指定的位置全部的内容,包括:android开发中 linearlayout中如何将子控件动态插入指定的位置、PyInstaller 无法打包完成后,运行exe无反应、如何使用 wxwidgets开发界面等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/9453682.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-28
下一篇 2023-04-28

发表评论

登录后才能评论

评论列表(0条)

保存